PageRenderTime 172ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/WCFWebApi/test/cit/unit/System.Net.Http.Test.Unit/Headers/HttpRequestHeadersTest.cs

#
C# | 1503 lines | 1200 code | 277 blank | 26 comment | 17 complexity | e657b1ecb3fc390b8c85736090d3afce MD5 | raw file
Possible License(s): CC-BY-SA-3.0, Apache-2.0
  1. using System;
  2. using System.Text;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using Microsoft.VisualStudio.TestTools.UnitTesting;
  6. using System.Net.Http.Headers;
  7. using System.Net.Test.Common;
  8. using System.Net.Mail;
  9. using System.Net.Test.Common.Logging;
  10. namespace System.Net.Http.Test.Headers
  11. {
  12. [TestClass]
  13. public class HttpRequestHeadersTest
  14. {
  15. private HttpRequestHeaders headers;
  16. [TestInitialize]
  17. public void TestInitialize()
  18. {
  19. headers = new HttpRequestHeaders();
  20. }
  21. #region Request headers
  22. [TestMethod]
  23. [ExpectedException(typeof(FormatException))]
  24. public void Accept_AddInvalidValueUsingUnusualCasing_ParserRetrievedUsingCaseInsensitiveComparison()
  25. {
  26. // Use uppercase header name to make sure the parser gets retrieved using case-insensitive comparison.
  27. headers.Add("AcCePt", "this is invalid");
  28. }
  29. [TestMethod]
  30. public void Accept_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  31. {
  32. MediaTypeWithQualityHeaderValue value1 = new MediaTypeWithQualityHeaderValue("text/plain");
  33. value1.CharSet = "utf-8";
  34. value1.Quality = 0.5;
  35. value1.Parameters.Add(new NameValueHeaderValue("custom", "value"));
  36. MediaTypeWithQualityHeaderValue value2 = new MediaTypeWithQualityHeaderValue("text/plain");
  37. value2.CharSet = "iso-8859-1";
  38. value2.Quality = 0.3868;
  39. Assert.AreEqual(0, headers.Accept.Count, "Collection expected to be empty on first call.");
  40. headers.Accept.Add(value1);
  41. headers.Accept.Add(value2);
  42. Assert.AreEqual(2, headers.Accept.Count, "Count");
  43. Assert.AreEqual(value1, headers.Accept.ElementAt(0), "Accept[0] expected to be value1.");
  44. Assert.AreEqual(value2, headers.Accept.ElementAt(1), "Accept[1] expected to be value2.");
  45. headers.Accept.Clear();
  46. Assert.AreEqual(0, headers.Accept.Count, "Count after Clear().");
  47. }
  48. [TestMethod]
  49. public void Accept_ReadEmptyProperty_EmptyCollection()
  50. {
  51. HttpRequestMessage request = new HttpRequestMessage();
  52. Assert.AreEqual(0, request.Headers.Accept.Count);
  53. // Copy to another list
  54. List<MediaTypeWithQualityHeaderValue> accepts = request.Headers.Accept.ToList();
  55. Assert.AreEqual(0, accepts.Count);
  56. accepts = new List<MediaTypeWithQualityHeaderValue>(request.Headers.Accept);
  57. Assert.AreEqual(0, accepts.Count);
  58. }
  59. [TestMethod]
  60. public void Accept_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  61. {
  62. headers.AddWithoutValidation("Accept",
  63. ",, , ,,text/plain; charset=iso-8859-1; q=1.0,\r\n */xml; charset=utf-8; q=0.5,,,");
  64. MediaTypeWithQualityHeaderValue value1 = new MediaTypeWithQualityHeaderValue("text/plain");
  65. value1.CharSet = "iso-8859-1";
  66. value1.Quality = 1.0;
  67. MediaTypeWithQualityHeaderValue value2 = new MediaTypeWithQualityHeaderValue("*/xml");
  68. value2.CharSet = "utf-8";
  69. value2.Quality = 0.5;
  70. Assert.AreEqual(value1, headers.Accept.ElementAt(0), "Accept[0]");
  71. Assert.AreEqual(value2, headers.Accept.ElementAt(1), "Accept[1]");
  72. }
  73. [TestMethod]
  74. public void Accept_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  75. {
  76. // Add a valid media-type with an invalid quality value
  77. headers.AddWithoutValidation("Accept", "text/plain; q=a"); // invalid quality
  78. Assert.IsNotNull(headers.Accept.First(), "Accept first value");
  79. Assert.IsNull(headers.Accept.First().Quality, "Accept.Quality"); // No quality value shown
  80. Assert.AreEqual("text/plain; q=a", headers.Accept.First().ToString(), "ToString()");
  81. headers.Clear();
  82. headers.AddWithoutValidation("Accept", "text/plain application/xml"); // no separator
  83. Assert.AreEqual(0, headers.Accept.Count, "Accept.Count");
  84. Assert.AreEqual(1, headers.GetValues("Accept").Count(), "Accept.Count");
  85. Assert.AreEqual("text/plain application/xml", headers.GetValues("Accept").First(), "Accept value");
  86. }
  87. [TestMethod]
  88. public void AcceptCharset_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  89. {
  90. Assert.AreEqual(0, headers.AcceptCharset.Count, "Collection expected to be empty on first call.");
  91. headers.AcceptCharset.Add(new StringWithQualityHeaderValue("iso-8859-5"));
  92. headers.AcceptCharset.Add(new StringWithQualityHeaderValue("unicode-1-1", 0.8));
  93. Assert.AreEqual(2, headers.AcceptCharset.Count, "Count");
  94. Assert.AreEqual(new StringWithQualityHeaderValue("iso-8859-5"), headers.AcceptCharset.ElementAt(0),
  95. "AcceptCharset[0]");
  96. Assert.AreEqual(new StringWithQualityHeaderValue("unicode-1-1", 0.8), headers.AcceptCharset.ElementAt(1),
  97. "AcceptCharset[1]");
  98. headers.AcceptCharset.Clear();
  99. Assert.AreEqual(0, headers.AcceptCharset.Count, "Count after Clear().");
  100. }
  101. [TestMethod]
  102. public void AcceptCharset_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  103. {
  104. headers.AddWithoutValidation("Accept-Charset", ", ,,iso-8859-5 , \r\n utf-8 ; q=0.300 ,,,");
  105. Assert.AreEqual(new StringWithQualityHeaderValue("iso-8859-5"),
  106. headers.AcceptCharset.ElementAt(0), "AcceptCharset[0]");
  107. Assert.AreEqual(new StringWithQualityHeaderValue("utf-8", 0.3),
  108. headers.AcceptCharset.ElementAt(1), "AcceptCharset[1]");
  109. }
  110. [TestMethod]
  111. public void AcceptCharset_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  112. {
  113. headers.AddWithoutValidation("Accept-Charset", "iso-8859-5 utf-8"); // no separator
  114. Assert.AreEqual(0, headers.AcceptCharset.Count, "Accept.Count");
  115. Assert.AreEqual(1, headers.GetValues("Accept-Charset").Count(), "Accept-Charset.Count");
  116. Assert.AreEqual("iso-8859-5 utf-8", headers.GetValues("Accept-Charset").First(), "Accept-Charset value");
  117. headers.Clear();
  118. headers.AddWithoutValidation("Accept-Charset", "utf-8; q=1; q=0.3");
  119. Assert.AreEqual(0, headers.AcceptCharset.Count, "AcceptCharset.Count");
  120. Assert.AreEqual(1, headers.GetValues("Accept-Charset").Count(), "Accept-Charset.Count");
  121. Assert.AreEqual("utf-8; q=1; q=0.3", headers.GetValues("Accept-Charset").First(), "Accept-Charset value");
  122. }
  123. [TestMethod]
  124. public void AcceptCharset_AddMultipleValuesAndGetValueString_AllValuesAddedUsingTheCorrectDelimiter()
  125. {
  126. headers.AddWithoutValidation("Accept-Charset", "invalid value");
  127. headers.Add("Accept-Charset", "utf-8");
  128. headers.AcceptCharset.Add(new StringWithQualityHeaderValue("iso-8859-5", 0.5));
  129. foreach (var header in headers.GetHeaderStrings())
  130. {
  131. Assert.AreEqual("Accept-Charset", header.Key);
  132. Assert.AreEqual("utf-8, iso-8859-5; q=0.5, invalid value", header.Value);
  133. }
  134. }
  135. [TestMethod]
  136. public void AcceptEncoding_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  137. {
  138. Assert.AreEqual(0, headers.AcceptEncoding.Count, "Collection expected to be empty on first call.");
  139. headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("compress", 0.9));
  140. headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
  141. Assert.AreEqual(2, headers.AcceptEncoding.Count, "Count");
  142. Assert.AreEqual(new StringWithQualityHeaderValue("compress", 0.9), headers.AcceptEncoding.ElementAt(0),
  143. "AcceptEncoding[0]");
  144. Assert.AreEqual(new StringWithQualityHeaderValue("gzip"), headers.AcceptEncoding.ElementAt(1),
  145. "AcceptEncoding[1]");
  146. headers.AcceptEncoding.Clear();
  147. Assert.AreEqual(0, headers.AcceptEncoding.Count, "Count after Clear().");
  148. }
  149. [TestMethod]
  150. public void AcceptEncoding_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  151. {
  152. headers.AddWithoutValidation("Accept-Encoding", ", gzip; q=1.0, identity; q=0.5, *;q=0, ");
  153. Assert.AreEqual(new StringWithQualityHeaderValue("gzip", 1),
  154. headers.AcceptEncoding.ElementAt(0), "AcceptEncoding[0]");
  155. Assert.AreEqual(new StringWithQualityHeaderValue("identity", 0.5),
  156. headers.AcceptEncoding.ElementAt(1), "AcceptEncoding[1]");
  157. Assert.AreEqual(new StringWithQualityHeaderValue("*", 0),
  158. headers.AcceptEncoding.ElementAt(2), "AcceptEncoding[2]");
  159. headers.AcceptEncoding.Clear();
  160. headers.AddWithoutValidation("Accept-Encoding", "");
  161. Assert.AreEqual(0, headers.AcceptEncoding.Count, "Count after Clear().");
  162. Assert.IsFalse(headers.Contains("Accept-Encoding"));
  163. }
  164. [TestMethod]
  165. public void AcceptEncoding_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  166. {
  167. headers.AddWithoutValidation("Accept-Encoding", "gzip deflate"); // no separator
  168. Assert.AreEqual(0, headers.AcceptEncoding.Count, "AcceptEncoding.Count");
  169. Assert.AreEqual(1, headers.GetValues("Accept-Encoding").Count(), "Accept-Encoding.Count");
  170. Assert.AreEqual("gzip deflate", headers.GetValues("Accept-Encoding").First(), "Accept-Encoding value");
  171. headers.Clear();
  172. headers.AddWithoutValidation("Accept-Encoding", "compress; q=1; gzip");
  173. Assert.AreEqual(0, headers.AcceptEncoding.Count, "AcceptEncoding.Count");
  174. Assert.AreEqual(1, headers.GetValues("Accept-Encoding").Count(), "Accept-Encoding.Count");
  175. Assert.AreEqual("compress; q=1; gzip", headers.GetValues("Accept-Encoding").First(), "Accept-Encoding value");
  176. }
  177. [TestMethod]
  178. public void AcceptLanguage_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  179. {
  180. Assert.AreEqual(0, headers.AcceptLanguage.Count, "Collection expected to be empty on first call.");
  181. headers.AcceptLanguage.Add(new StringWithQualityHeaderValue("da"));
  182. headers.AcceptLanguage.Add(new StringWithQualityHeaderValue("en-GB", 0.8));
  183. headers.AcceptLanguage.Add(new StringWithQualityHeaderValue("en", 0.7));
  184. Assert.AreEqual(3, headers.AcceptLanguage.Count, "Count");
  185. Assert.AreEqual(new StringWithQualityHeaderValue("da"), headers.AcceptLanguage.ElementAt(0),
  186. "AcceptLanguage[0]");
  187. Assert.AreEqual(new StringWithQualityHeaderValue("en-GB", 0.8), headers.AcceptLanguage.ElementAt(1),
  188. "AcceptLanguage[1]");
  189. Assert.AreEqual(new StringWithQualityHeaderValue("en", 0.7), headers.AcceptLanguage.ElementAt(2),
  190. "AcceptLanguage[2]");
  191. headers.AcceptLanguage.Clear();
  192. Assert.AreEqual(0, headers.AcceptLanguage.Count, "Count after Clear().");
  193. }
  194. [TestMethod]
  195. public void AcceptLanguage_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  196. {
  197. headers.AddWithoutValidation("Accept-Language", " , de-DE;q=0.9,de-AT;q=0.5,*;q=0.010 , ");
  198. Assert.AreEqual(new StringWithQualityHeaderValue("de-DE", 0.9),
  199. headers.AcceptLanguage.ElementAt(0), "AcceptLanguage[0]");
  200. Assert.AreEqual(new StringWithQualityHeaderValue("de-AT", 0.5),
  201. headers.AcceptLanguage.ElementAt(1), "AcceptLanguage[1]");
  202. Assert.AreEqual(new StringWithQualityHeaderValue("*", 0.01),
  203. headers.AcceptLanguage.ElementAt(2), "AcceptLanguage[2]");
  204. headers.AcceptLanguage.Clear();
  205. headers.AddWithoutValidation("Accept-Language", "");
  206. Assert.AreEqual(0, headers.AcceptLanguage.Count, "Count after Clear().");
  207. Assert.IsFalse(headers.Contains("Accept-Language"));
  208. }
  209. [TestMethod]
  210. public void AcceptLanguage_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  211. {
  212. headers.AddWithoutValidation("Accept-Language", "de -DE"); // no separator
  213. Assert.AreEqual(0, headers.AcceptLanguage.Count, "AcceptLanguage.Count");
  214. Assert.AreEqual(1, headers.GetValues("Accept-Language").Count(), "Accept-Language.Count");
  215. Assert.AreEqual("de -DE", headers.GetValues("Accept-Language").First(), "Accept-Language value");
  216. headers.Clear();
  217. headers.AddWithoutValidation("Accept-Language", "en; q=0.4,[");
  218. Assert.AreEqual(0, headers.AcceptLanguage.Count, "AcceptLanguage.Count");
  219. Assert.AreEqual(1, headers.GetValues("Accept-Language").Count(), "Accept-Language.Count");
  220. Assert.AreEqual("en; q=0.4,[", headers.GetValues("Accept-Language").First(), "Accept-Language value");
  221. }
  222. [TestMethod]
  223. public void Expect_Add100Continue_Success()
  224. {
  225. // use non-default casing to make sure we do case-insensitive comparison.
  226. headers.Expect.Add(new NameValueWithParametersHeaderValue("100-CONTINUE"));
  227. Assert.IsTrue(headers.ExpectContinue == true);
  228. Assert.AreEqual(1, headers.Expect.Count);
  229. }
  230. [TestMethod]
  231. public void Expect_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  232. {
  233. Assert.AreEqual(0, headers.Expect.Count, "Expect expected to be empty on first call.");
  234. Assert.IsNull(headers.ExpectContinue, "ExpectContinue should be null by default.");
  235. headers.Expect.Add(new NameValueWithParametersHeaderValue("custom1"));
  236. headers.Expect.Add(new NameValueWithParametersHeaderValue("custom2"));
  237. headers.ExpectContinue = true;
  238. // Connection collection has 2 values plus '100-Continue'
  239. Assert.AreEqual(3, headers.Expect.Count, "Expect.Count");
  240. Assert.AreEqual(3, headers.GetValues("Expect").Count(), "Expect header value count.");
  241. Assert.IsTrue(headers.ExpectContinue == true, "ExpectContinue == true");
  242. Assert.AreEqual(new NameValueWithParametersHeaderValue("custom1"), headers.Expect.ElementAt(0),
  243. "Expect[0]");
  244. Assert.AreEqual(new NameValueWithParametersHeaderValue("custom2"), headers.Expect.ElementAt(1),
  245. "Expect[1]");
  246. // Remove '100-continue' value from store. But leave other 'Expect' values.
  247. headers.ExpectContinue = false;
  248. Assert.IsTrue(headers.ExpectContinue == false, "ExpectContinue == false");
  249. Assert.AreEqual(2, headers.Expect.Count, "Expect.Count");
  250. Assert.AreEqual(new NameValueWithParametersHeaderValue("custom1"), headers.Expect.ElementAt(0),
  251. "Expect[0]");
  252. Assert.AreEqual(new NameValueWithParametersHeaderValue("custom2"), headers.Expect.ElementAt(1),
  253. "Expect[1]");
  254. headers.ExpectContinue = true;
  255. headers.Expect.Clear();
  256. Assert.IsTrue(headers.ExpectContinue == false, "ExpectContinue should be modified by Expect.Clear().");
  257. Assert.AreEqual(0, headers.Expect.Count, "Count after Clear().");
  258. IEnumerable<string> dummyArray;
  259. Assert.IsFalse(headers.TryGetValues("Expect", out dummyArray), "Expect header count after Expect.Clear().");
  260. // Remove '100-continue' value from store. Since there are no other 'Expect' values, remove whole header.
  261. headers.ExpectContinue = false;
  262. Assert.IsTrue(headers.ExpectContinue == false, "ExpectContinue == false");
  263. Assert.AreEqual(0, headers.Expect.Count, "Expect.Count");
  264. Assert.IsFalse(headers.Contains("Expect"));
  265. headers.ExpectContinue = null;
  266. Assert.IsNull(headers.ExpectContinue, "ExpectContinue");
  267. }
  268. [TestMethod]
  269. public void Expect_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  270. {
  271. headers.AddWithoutValidation("Expect",
  272. ", , 100-continue, name1 = value1, name2; param2=paramValue2, name3=value3; param3 ,");
  273. // Connection collection has 3 values plus '100-continue'
  274. Assert.AreEqual(4, headers.Expect.Count, "Expect.Count");
  275. Assert.AreEqual(4, headers.GetValues("Expect").Count(), "Expect header value count.");
  276. Assert.IsTrue(headers.ExpectContinue == true, "ExpectContinue expected to be true.");
  277. Assert.AreEqual(new NameValueWithParametersHeaderValue("100-continue"),
  278. headers.Expect.ElementAt(0), "Expect[0]");
  279. Assert.AreEqual(new NameValueWithParametersHeaderValue("name1", "value1"),
  280. headers.Expect.ElementAt(1), "Expect[1]");
  281. NameValueWithParametersHeaderValue expected2 = new NameValueWithParametersHeaderValue("name2");
  282. expected2.Parameters.Add(new NameValueHeaderValue("param2", "paramValue2"));
  283. Assert.AreEqual(expected2, headers.Expect.ElementAt(2), "Expect[2]");
  284. NameValueWithParametersHeaderValue expected3 = new NameValueWithParametersHeaderValue("name3", "value3");
  285. expected3.Parameters.Add(new NameValueHeaderValue("param3"));
  286. Assert.AreEqual(expected3, headers.Expect.ElementAt(3), "Expect[3]");
  287. headers.Expect.Clear();
  288. Assert.IsNull(headers.ExpectContinue, "ExpectContinue should be modified by Expect.Clear().");
  289. Assert.AreEqual(0, headers.Expect.Count, "Count after Clear().");
  290. IEnumerable<string> dummyArray;
  291. Assert.IsFalse(headers.TryGetValues("Expect", out dummyArray), "Expect header count after Expect.Clear().");
  292. }
  293. [TestMethod]
  294. public void Expect_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  295. {
  296. headers.AddWithoutValidation("Expect", "100-continue other"); // no separator
  297. Assert.AreEqual(0, headers.Expect.Count, "Expect.Count");
  298. Assert.AreEqual(1, headers.GetValues("Expect").Count(), "Expect.Count");
  299. Assert.AreEqual("100-continue other", headers.GetValues("Expect").First(), "Expect value");
  300. }
  301. [TestMethod]
  302. public void Host_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  303. {
  304. Assert.IsNull(headers.Host, "Host should be null by default.");
  305. headers.Host = "host";
  306. Assert.AreEqual("host", headers.Host);
  307. headers.Host = null;
  308. Assert.IsNull(headers.Host, "Host should be null after setting it to null.");
  309. Assert.IsFalse(headers.Contains("Host"),
  310. "Header store should not contain a header 'Host' after setting it to null.");
  311. ExceptionAssert.ThrowsFormat(() => headers.Host = "invalid host", "Setting invalid Host value should throw.");
  312. }
  313. [TestMethod]
  314. public void Host_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  315. {
  316. headers.AddWithoutValidation("Host", "host:80");
  317. Assert.AreEqual("host:80", headers.Host);
  318. }
  319. [TestMethod]
  320. public void IfMatch_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  321. {
  322. Assert.AreEqual(0, headers.IfMatch.Count, "IfMatch expected to be empty on first call.");
  323. headers.IfMatch.Add(new EntityTagHeaderValue("\"custom1\""));
  324. headers.IfMatch.Add(new EntityTagHeaderValue("\"custom2\"", true));
  325. Assert.AreEqual(2, headers.IfMatch.Count, "IfMatch.Count");
  326. Assert.AreEqual(2, headers.GetValues("If-Match").Count(), "If-Match header value count.");
  327. Assert.AreEqual(new EntityTagHeaderValue("\"custom1\""), headers.IfMatch.ElementAt(0),
  328. "IfMatch[0]");
  329. Assert.AreEqual(new EntityTagHeaderValue("\"custom2\"", true), headers.IfMatch.ElementAt(1),
  330. "IfMatch[1]");
  331. headers.IfMatch.Clear();
  332. Assert.AreEqual(0, headers.IfMatch.Count, "Count after Clear().");
  333. Assert.IsFalse(headers.Contains("If-Match"), "Header store should not contain 'If-Match'");
  334. }
  335. [TestMethod]
  336. public void IfMatch_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  337. {
  338. headers.AddWithoutValidation("If-Match", ", , W/\"tag1\", \"tag2\", W/\"tag3\" ,");
  339. Assert.AreEqual(3, headers.IfMatch.Count, "IfMatch.Count");
  340. Assert.AreEqual(3, headers.GetValues("If-Match").Count(), "If-Match header value count.");
  341. Assert.AreEqual(new EntityTagHeaderValue("\"tag1\"", true), headers.IfMatch.ElementAt(0),
  342. "IfMatch[0]");
  343. Assert.AreEqual(new EntityTagHeaderValue("\"tag2\"", false), headers.IfMatch.ElementAt(1),
  344. "IfMatch[1]");
  345. Assert.AreEqual(new EntityTagHeaderValue("\"tag3\"", true), headers.IfMatch.ElementAt(2),
  346. "IfMatch[2]");
  347. headers.IfMatch.Clear();
  348. headers.Add("If-Match", "*");
  349. Assert.AreEqual(1, headers.IfMatch.Count, "Count after Clear().");
  350. Assert.AreSame(EntityTagHeaderValue.Any, headers.IfMatch.ElementAt(0), "IfMatch[0]");
  351. }
  352. [TestMethod]
  353. public void IfMatch_UseAddMethodWithInvalidInput_PropertyNotUpdated()
  354. {
  355. headers.AddWithoutValidation("If-Match", "W/\"tag1\" \"tag2\""); // no separator
  356. Assert.AreEqual(0, headers.IfMatch.Count, "IfMatch.Count");
  357. Assert.AreEqual(1, headers.GetValues("If-Match").Count(), "If-Match header value count.");
  358. }
  359. [TestMethod]
  360. public void IfNoneMatch_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  361. {
  362. Assert.AreEqual(0, headers.IfNoneMatch.Count, "IfNoneMatch expected to be empty on first call.");
  363. headers.IfNoneMatch.Add(new EntityTagHeaderValue("\"custom1\""));
  364. headers.IfNoneMatch.Add(new EntityTagHeaderValue("\"custom2\"", true));
  365. Assert.AreEqual(2, headers.IfNoneMatch.Count, "IfNoneMatch.Count");
  366. Assert.AreEqual(2, headers.GetValues("If-None-Match").Count(), "If-None-Match header value count.");
  367. Assert.AreEqual(new EntityTagHeaderValue("\"custom1\""), headers.IfNoneMatch.ElementAt(0),
  368. "IfNoneMatch[0]");
  369. Assert.AreEqual(new EntityTagHeaderValue("\"custom2\"", true), headers.IfNoneMatch.ElementAt(1),
  370. "IfNoneMatch[1]");
  371. headers.IfNoneMatch.Clear();
  372. Assert.AreEqual(0, headers.IfNoneMatch.Count, "Count after Clear().");
  373. Assert.IsFalse(headers.Contains("If-None-Match"), "Header store should not contain 'If-None-Match'");
  374. }
  375. [TestMethod]
  376. public void IfNoneMatch_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  377. {
  378. headers.AddWithoutValidation("If-None-Match", "W/\"tag1\", \"tag2\", W/\"tag3\"");
  379. Assert.AreEqual(3, headers.IfNoneMatch.Count, "IfNoneMatch.Count");
  380. Assert.AreEqual(3, headers.GetValues("If-None-Match").Count(), "If-None-Match header value count.");
  381. Assert.AreEqual(new EntityTagHeaderValue("\"tag1\"", true), headers.IfNoneMatch.ElementAt(0),
  382. "IfNoneMatch[0]");
  383. Assert.AreEqual(new EntityTagHeaderValue("\"tag2\"", false), headers.IfNoneMatch.ElementAt(1),
  384. "IfNoneMatch[1]");
  385. Assert.AreEqual(new EntityTagHeaderValue("\"tag3\"", true), headers.IfNoneMatch.ElementAt(2),
  386. "IfNoneMatch[2]");
  387. headers.IfNoneMatch.Clear();
  388. headers.Add("If-None-Match", "*");
  389. Assert.AreEqual(1, headers.IfNoneMatch.Count, "Count after Clear().");
  390. Assert.AreSame(EntityTagHeaderValue.Any, headers.IfNoneMatch.ElementAt(0), "IfNoneMatch[0]");
  391. }
  392. [TestMethod]
  393. public void TE_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  394. {
  395. TransferCodingWithQualityHeaderValue value1 = new TransferCodingWithQualityHeaderValue("custom");
  396. value1.Quality = 0.5;
  397. value1.Parameters.Add(new NameValueHeaderValue("name", "value"));
  398. TransferCodingWithQualityHeaderValue value2 = new TransferCodingWithQualityHeaderValue("custom");
  399. value2.Quality = 0.3868;
  400. Assert.AreEqual(0, headers.TE.Count, "Collection expected to be empty on first call.");
  401. headers.TE.Add(value1);
  402. headers.TE.Add(value2);
  403. Assert.AreEqual(2, headers.TE.Count, "Count");
  404. Assert.AreEqual(value1, headers.TE.ElementAt(0), "TE[0] expected to be value1.");
  405. Assert.AreEqual(value2, headers.TE.ElementAt(1), "TE[1] expected to be value2.");
  406. headers.TE.Clear();
  407. Assert.AreEqual(0, headers.TE.Count, "Count after Clear().");
  408. }
  409. [TestMethod]
  410. public void TE_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  411. {
  412. headers.AddWithoutValidation("TE",
  413. ",custom1; param1=value1; q=1.0,,\r\n custom2; param2=value2; q=0.5 ,");
  414. TransferCodingWithQualityHeaderValue value1 = new TransferCodingWithQualityHeaderValue("custom1");
  415. value1.Parameters.Add(new NameValueHeaderValue("param1", "value1"));
  416. value1.Quality = 1.0;
  417. TransferCodingWithQualityHeaderValue value2 = new TransferCodingWithQualityHeaderValue("custom2");
  418. value2.Parameters.Add(new NameValueHeaderValue("param2", "value2"));
  419. value2.Quality = 0.5;
  420. Assert.AreEqual(value1, headers.TE.ElementAt(0), "TE[0]");
  421. Assert.AreEqual(value2, headers.TE.ElementAt(1), "TE[1]");
  422. headers.Clear();
  423. headers.AddWithoutValidation("TE", "");
  424. Assert.IsFalse(headers.Contains("TE"), "'TE' header should not be added if it just has empty values.");
  425. }
  426. [TestMethod]
  427. public void Range_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  428. {
  429. Assert.IsNull(headers.Range, "Uninitialized Range");
  430. RangeHeaderValue value = new RangeHeaderValue(1, 2);
  431. headers.Range = value;
  432. Assert.AreEqual(value, headers.Range, "Initialized Range");
  433. headers.Range = null;
  434. Assert.IsNull(headers.Range, "Range after setting it to null.");
  435. }
  436. [TestMethod]
  437. public void Range_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  438. {
  439. headers.AddWithoutValidation("Range", "custom= , ,1-2, -4 , ");
  440. RangeHeaderValue value = new RangeHeaderValue();
  441. value.Unit = "custom";
  442. value.Ranges.Add(new RangeItemHeaderValue(1, 2));
  443. value.Ranges.Add(new RangeItemHeaderValue(null, 4));
  444. Assert.AreEqual(value, headers.Range, "Initialized ContentRange");
  445. }
  446. [TestMethod]
  447. public void Authorization_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  448. {
  449. Assert.IsNull(headers.Authorization, "Authorization should be null by default.");
  450. headers.Authorization = new AuthenticationHeaderValue("Basic", "QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
  451. Assert.AreEqual(new AuthenticationHeaderValue("Basic", "QWxhZGRpbjpvcGVuIHNlc2FtZQ=="), headers.Authorization);
  452. headers.Authorization = null;
  453. Assert.IsNull(headers.Authorization, "Authorization should be null after setting it to null.");
  454. Assert.IsFalse(headers.Contains("Authorization"),
  455. "Header store should not contain a header 'Authorization' after setting it to null.");
  456. }
  457. [TestMethod]
  458. public void Authorization_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  459. {
  460. headers.AddWithoutValidation("Authorization", "NTLM blob");
  461. Assert.AreEqual(new AuthenticationHeaderValue("NTLM", "blob"), headers.Authorization);
  462. }
  463. [TestMethod]
  464. public void ProxyAuthorization_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  465. {
  466. Assert.IsNull(headers.ProxyAuthorization, "ProxyAuthorization should be null by default.");
  467. headers.ProxyAuthorization = new AuthenticationHeaderValue("Basic", "QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
  468. Assert.AreEqual(new AuthenticationHeaderValue("Basic", "QWxhZGRpbjpvcGVuIHNlc2FtZQ=="),
  469. headers.ProxyAuthorization);
  470. headers.ProxyAuthorization = null;
  471. Assert.IsNull(headers.ProxyAuthorization, "ProxyAuthorization should be null after setting it to null.");
  472. Assert.IsFalse(headers.Contains("ProxyAuthorization"),
  473. "Header store should not contain a header 'ProxyAuthorization' after setting it to null.");
  474. }
  475. [TestMethod]
  476. public void ProxyAuthorization_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  477. {
  478. headers.AddWithoutValidation("Proxy-Authorization", "NTLM blob");
  479. Assert.AreEqual(new AuthenticationHeaderValue("NTLM", "blob"), headers.ProxyAuthorization);
  480. }
  481. [TestMethod]
  482. public void UserAgent_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  483. {
  484. Assert.AreEqual(0, headers.UserAgent.Count, "UserAgent expected to be empty on first call.");
  485. headers.UserAgent.Add(new ProductInfoHeaderValue("(custom1)"));
  486. headers.UserAgent.Add(new ProductInfoHeaderValue("custom2", "1.1"));
  487. Assert.AreEqual(2, headers.UserAgent.Count, "UserAgent.Count");
  488. Assert.AreEqual(2, headers.GetValues("User-Agent").Count(), "User-Agent header value count.");
  489. Assert.AreEqual(new ProductInfoHeaderValue("(custom1)"), headers.UserAgent.ElementAt(0), "UserAgent[0]");
  490. Assert.AreEqual(new ProductInfoHeaderValue("custom2", "1.1"), headers.UserAgent.ElementAt(1), "UserAgent[1]");
  491. headers.UserAgent.Clear();
  492. Assert.AreEqual(0, headers.UserAgent.Count, "Count after Clear().");
  493. Assert.IsFalse(headers.Contains("User-Agent"), "User-Agent header should be removed after calling Clear().");
  494. headers.UserAgent.Add(new ProductInfoHeaderValue("(comment)"));
  495. headers.UserAgent.Remove(new ProductInfoHeaderValue("(comment)"));
  496. Assert.AreEqual(0, headers.UserAgent.Count, "Count after Remove().");
  497. Assert.IsFalse(headers.Contains("User-Agent"), "User-Agent header should be removed after removing last value.");
  498. }
  499. [TestMethod]
  500. public void UserAgent_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  501. {
  502. headers.AddWithoutValidation("User-Agent", "Opera/9.80 (Windows NT 6.1; U; en) Presto/2.6.30 Version/10.63");
  503. Assert.AreEqual(4, headers.UserAgent.Count, "UserAgent.Count");
  504. Assert.AreEqual(4, headers.GetValues("User-Agent").Count(), "User-Agent header value count.");
  505. Assert.AreEqual(new ProductInfoHeaderValue("Opera", "9.80"), headers.UserAgent.ElementAt(0), "UserAgent[0]");
  506. Assert.AreEqual(new ProductInfoHeaderValue("(Windows NT 6.1; U; en)"), headers.UserAgent.ElementAt(1), "UserAgent[1]");
  507. Assert.AreEqual(new ProductInfoHeaderValue("Presto", "2.6.30"), headers.UserAgent.ElementAt(2), "UserAgent[2]");
  508. Assert.AreEqual(new ProductInfoHeaderValue("Version", "10.63"), headers.UserAgent.ElementAt(3), "UserAgent[3]");
  509. headers.UserAgent.Clear();
  510. Assert.AreEqual(0, headers.UserAgent.Count, "Count after Clear().");
  511. Assert.IsFalse(headers.Contains("User-Agent"), "User-Agent header should be removed after calling Clear().");
  512. }
  513. [TestMethod]
  514. public void UserAgent_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  515. {
  516. headers.AddWithoutValidation("User-Agent", "custom会");
  517. Assert.IsNull(headers.GetParsedValues("User-Agent"), "Parsed value.");
  518. Assert.AreEqual(1, headers.GetValues("User-Agent").Count(), "Store value count");
  519. Assert.AreEqual("custom会", headers.GetValues("User-Agent").First(), "Store value");
  520. headers.Clear();
  521. // Note that "User-Agent" uses whitespaces as separators, so the following is an invalid value
  522. headers.AddWithoutValidation("User-Agent", "custom1, custom2");
  523. Assert.IsNull(headers.GetParsedValues("User-Agent"), "Parsed value.");
  524. Assert.AreEqual(1, headers.GetValues("User-Agent").Count(), "Store value count");
  525. Assert.AreEqual("custom1, custom2", headers.GetValues("User-Agent").First(), "Store value");
  526. headers.Clear();
  527. headers.AddWithoutValidation("User-Agent", "custom1, ");
  528. Assert.IsNull(headers.GetParsedValues("User-Agent"), "Parsed value.");
  529. Assert.AreEqual(1, headers.GetValues("User-Agent").Count(), "Store value count");
  530. Assert.AreEqual("custom1, ", headers.GetValues("User-Agent").First(), "Store value");
  531. headers.Clear();
  532. headers.AddWithoutValidation("User-Agent", ",custom1");
  533. Assert.IsNull(headers.GetParsedValues("User-Agent"), "Parsed value.");
  534. Assert.AreEqual(1, headers.GetValues("User-Agent").Count(), "Store value count");
  535. Assert.AreEqual(",custom1", headers.GetValues("User-Agent").First(), "Store value");
  536. }
  537. [TestMethod]
  538. public void UserAgent_AddMultipleValuesAndGetValueString_AllValuesAddedUsingTheCorrectDelimiter()
  539. {
  540. headers.AddWithoutValidation("User-Agent", "custom会");
  541. headers.Add("User-Agent", "custom2/1.1");
  542. headers.UserAgent.Add(new ProductInfoHeaderValue("(comment)"));
  543. foreach (var header in headers.GetHeaderStrings())
  544. {
  545. Assert.AreEqual("User-Agent", header.Key);
  546. Assert.AreEqual("custom2/1.1 (comment) custom会", header.Value);
  547. }
  548. }
  549. [TestMethod]
  550. public void IfRange_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  551. {
  552. Assert.IsNull(headers.IfRange, "IfRange expected to be null on first call.");
  553. headers.IfRange = new RangeConditionHeaderValue("\"x\"");
  554. Assert.AreEqual(1, headers.GetValues("If-Range").Count(), "If-Range header value count.");
  555. Assert.AreEqual(new RangeConditionHeaderValue("\"x\""), headers.IfRange, "IfRange value after setting it.");
  556. headers.IfRange = null;
  557. Assert.IsNull(headers.IfRange, "IfRange value after setting it to null.");
  558. Assert.IsFalse(headers.Contains("If-Range"), "If-Range header should be removed after calling Clear().");
  559. }
  560. [TestMethod]
  561. public void IfRange_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  562. {
  563. headers.AddWithoutValidation("If-Range", " W/\"tag\" ");
  564. Assert.AreEqual(new RangeConditionHeaderValue(new EntityTagHeaderValue("\"tag\"", true)),
  565. headers.IfRange, "IfRange");
  566. Assert.AreEqual(1, headers.GetValues("If-Range").Count(), "If-Range header value count.");
  567. headers.IfRange = null;
  568. Assert.IsNull(headers.IfRange, "IfRange value after setting it to null.");
  569. Assert.IsFalse(headers.Contains("If-Range"), "If-Range header should be removed after calling Clear().");
  570. }
  571. [TestMethod]
  572. public void IfRange_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  573. {
  574. headers.AddWithoutValidation("If-Range", "\"tag\"会");
  575. Assert.IsNull(headers.GetParsedValues("If-Range"), "Parsed value.");
  576. Assert.AreEqual(1, headers.GetValues("If-Range").Count(), "Store value count");
  577. Assert.AreEqual("\"tag\"会", headers.GetValues("If-Range").First(), "Store value");
  578. headers.Clear();
  579. headers.AddWithoutValidation("If-Range", " \"tag\", ");
  580. Assert.IsNull(headers.GetParsedValues("If-Range"), "Parsed value.");
  581. Assert.AreEqual(1, headers.GetValues("If-Range").Count(), "Store value count");
  582. Assert.AreEqual(" \"tag\", ", headers.GetValues("If-Range").First(), "Store value");
  583. }
  584. [TestMethod]
  585. public void From_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  586. {
  587. Assert.IsNull(headers.From, "Host should be null by default.");
  588. headers.From = "info@example.com";
  589. Assert.AreEqual("info@example.com", headers.From);
  590. headers.From = null;
  591. Assert.IsNull(headers.From, "From should be null after setting it to null.");
  592. Assert.IsFalse(headers.Contains("From"),
  593. "Header store should not contain a header 'From' after setting it to null.");
  594. ExceptionAssert.ThrowsFormat(() => headers.From = " ", "' '");
  595. ExceptionAssert.ThrowsFormat(() => headers.From = "invalid email address", "invalid email address");
  596. }
  597. [TestMethod]
  598. public void From_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  599. {
  600. headers.AddWithoutValidation("From", " \"My Name\" info@example.com ");
  601. Assert.AreEqual("\"My Name\" info@example.com ", headers.From);
  602. // The following encoded string represents the character sequence "会员服务".
  603. headers.Clear();
  604. headers.AddWithoutValidation("From", "=?utf-8?Q?=E4=BC=9A=E5=91=98=E6=9C=8D=E5=8A=A1?= <info@example.com>");
  605. Assert.AreEqual("=?utf-8?Q?=E4=BC=9A=E5=91=98=E6=9C=8D=E5=8A=A1?= <info@example.com>", headers.From);
  606. }
  607. [TestMethod]
  608. public void From_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  609. {
  610. headers.AddWithoutValidation("From", " info@example.com ,");
  611. Assert.IsNull(headers.GetParsedValues("From"), "Parsed value.");
  612. Assert.AreEqual(1, headers.GetValues("From").Count(), "Store value count");
  613. Assert.AreEqual(" info@example.com ,", headers.GetValues("From").First(), "Store value");
  614. headers.Clear();
  615. headers.AddWithoutValidation("From", "info@");
  616. Assert.IsNull(headers.GetParsedValues("From"), "Parsed value.");
  617. Assert.AreEqual(1, headers.GetValues("From").Count(), "Store value count");
  618. Assert.AreEqual("info@", headers.GetValues("From").First(), "Store value");
  619. }
  620. [TestMethod]
  621. public void IfModifiedSince_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  622. {
  623. Assert.IsNull(headers.IfModifiedSince, "Host should be null by default.");
  624. DateTimeOffset expected = DateTimeOffset.Now;
  625. headers.IfModifiedSince = expected;
  626. Assert.AreEqual(expected, headers.IfModifiedSince);
  627. headers.IfModifiedSince = null;
  628. Assert.IsNull(headers.IfModifiedSince, "IfModifiedSince should be null after setting it to null.");
  629. Assert.IsFalse(headers.Contains("If-Modified-Since"),
  630. "Header store should not contain a header 'IfModifiedSince' after setting it to null.");
  631. }
  632. [TestMethod]
  633. public void IfModifiedSince_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  634. {
  635. headers.AddWithoutValidation("If-Modified-Since", " Sun, 06 Nov 1994 08:49:37 GMT ");
  636. Assert.AreEqual(new DateTimeOffset(1994, 11, 6, 8, 49, 37, TimeSpan.Zero), headers.IfModifiedSince);
  637. headers.Clear();
  638. headers.AddWithoutValidation("If-Modified-Since", "Sun, 06 Nov 1994 08:49:37 GMT");
  639. Assert.AreEqual(new DateTimeOffset(1994, 11, 6, 8, 49, 37, TimeSpan.Zero), headers.IfModifiedSince);
  640. }
  641. [TestMethod]
  642. public void IfModifiedSince_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  643. {
  644. headers.AddWithoutValidation("If-Modified-Since", " Sun, 06 Nov 1994 08:49:37 GMT ,");
  645. Assert.IsNull(headers.GetParsedValues("If-Modified-Since"), "Parsed value.");
  646. Assert.AreEqual(1, headers.GetValues("If-Modified-Since").Count(), "Store value count");
  647. Assert.AreEqual(" Sun, 06 Nov 1994 08:49:37 GMT ,", headers.GetValues("If-Modified-Since").First(),
  648. "Store value");
  649. headers.Clear();
  650. headers.AddWithoutValidation("If-Modified-Since", " Sun, 06 Nov ");
  651. Assert.IsNull(headers.GetParsedValues("If-Modified-Since"), "Parsed value.");
  652. Assert.AreEqual(1, headers.GetValues("If-Modified-Since").Count(), "Store value count");
  653. Assert.AreEqual(" Sun, 06 Nov ", headers.GetValues("If-Modified-Since").First(), "Store value");
  654. }
  655. [TestMethod]
  656. public void IfUnmodifiedSince_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  657. {
  658. Assert.IsNull(headers.IfUnmodifiedSince, "Host should be null by default.");
  659. DateTimeOffset expected = DateTimeOffset.Now;
  660. headers.IfUnmodifiedSince = expected;
  661. Assert.AreEqual(expected, headers.IfUnmodifiedSince);
  662. headers.IfUnmodifiedSince = null;
  663. Assert.IsNull(headers.IfUnmodifiedSince, "IfUnmodifiedSince should be null after setting it to null.");
  664. Assert.IsFalse(headers.Contains("If-Unmodified-Since"),
  665. "Header store should not contain a header 'IfUnmodifiedSince' after setting it to null.");
  666. }
  667. [TestMethod]
  668. public void IfUnmodifiedSince_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  669. {
  670. headers.AddWithoutValidation("If-Unmodified-Since", " Sun, 06 Nov 1994 08:49:37 GMT ");
  671. Assert.AreEqual(new DateTimeOffset(1994, 11, 6, 8, 49, 37, TimeSpan.Zero), headers.IfUnmodifiedSince);
  672. headers.Clear();
  673. headers.AddWithoutValidation("If-Unmodified-Since", "Sun, 06 Nov 1994 08:49:37 GMT");
  674. Assert.AreEqual(new DateTimeOffset(1994, 11, 6, 8, 49, 37, TimeSpan.Zero), headers.IfUnmodifiedSince);
  675. }
  676. [TestMethod]
  677. public void IfUnmodifiedSince_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  678. {
  679. headers.AddWithoutValidation("If-Unmodified-Since", " Sun, 06 Nov 1994 08:49:37 GMT ,");
  680. Assert.IsNull(headers.GetParsedValues("If-Unmodified-Since"), "Parsed value.");
  681. Assert.AreEqual(1, headers.GetValues("If-Unmodified-Since").Count(), "Store value count");
  682. Assert.AreEqual(" Sun, 06 Nov 1994 08:49:37 GMT ,", headers.GetValues("If-Unmodified-Since").First(),
  683. "Store value");
  684. headers.Clear();
  685. headers.AddWithoutValidation("If-Unmodified-Since", " Sun, 06 Nov ");
  686. Assert.IsNull(headers.GetParsedValues("If-Unmodified-Since"), "Parsed value.");
  687. Assert.AreEqual(1, headers.GetValues("If-Unmodified-Since").Count(), "Store value count");
  688. Assert.AreEqual(" Sun, 06 Nov ", headers.GetValues("If-Unmodified-Since").First(), "Store value");
  689. }
  690. [TestMethod]
  691. public void Referrer_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  692. {
  693. Assert.IsNull(headers.Referrer, "Host should be null by default.");
  694. Uri expected = new Uri("http://example.com/path/");
  695. headers.Referrer = expected;
  696. Assert.AreEqual(expected, headers.Referrer);
  697. headers.Referrer = null;
  698. Assert.IsNull(headers.Referrer, "Referrer should be null after setting it to null.");
  699. Assert.IsFalse(headers.Contains("Referer"),
  700. "Header store should not contain a header 'Referrer' after setting it to null.");
  701. }
  702. [TestMethod]
  703. public void Referrer_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  704. {
  705. headers.AddWithoutValidation("Referer", " http://www.example.com/path/?q=v ");
  706. Assert.AreEqual(new Uri("http://www.example.com/path/?q=v"), headers.Referrer);
  707. headers.Clear();
  708. headers.AddWithoutValidation("Referer", "/relative/uri/");
  709. Assert.AreEqual(new Uri("/relative/uri/", UriKind.Relative), headers.Referrer);
  710. }
  711. [TestMethod]
  712. public void Referrer_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  713. {
  714. headers.AddWithoutValidation("Referer", " http://example.com http://other");
  715. Assert.IsNull(headers.GetParsedValues("Referer"), "Parsed value.");
  716. Assert.AreEqual(1, headers.GetValues("Referer").Count(), "Store value count");
  717. Assert.AreEqual(" http://example.com http://other", headers.GetValues("Referer").First(), "Store value");
  718. headers.Clear();
  719. headers.AddWithoutValidation("Referer", "http://host /other");
  720. Assert.IsNull(headers.GetParsedValues("Referer"), "Parsed value.");
  721. Assert.AreEqual(1, headers.GetValues("Referer").Count(), "Store value count");
  722. Assert.AreEqual("http://host /other", headers.GetValues("Referer").First(), "Store value");
  723. }
  724. [TestMethod]
  725. public void MaxForwards_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  726. {
  727. Assert.IsNull(headers.MaxForwards, "Host should be null by default.");
  728. headers.MaxForwards = 15;
  729. Assert.AreEqual(15, headers.MaxForwards);
  730. headers.MaxForwards = null;
  731. Assert.IsNull(headers.MaxForwards, "MaxForwards should be null after setting it to null.");
  732. Assert.IsFalse(headers.Contains("Max-Forwards"),
  733. "Header store should not contain a header 'MaxForwards' after setting it to null.");
  734. // Make sure the header gets serialized correctly
  735. headers.MaxForwards = 12345;
  736. Assert.AreEqual("12345", headers.GetValues("Max-Forwards").First(), "Serialized header");
  737. }
  738. [TestMethod]
  739. public void MaxForwards_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  740. {
  741. headers.AddWithoutValidation("Max-Forwards", " 00123 ");
  742. Assert.AreEqual(123, headers.MaxForwards);
  743. headers.Clear();
  744. headers.AddWithoutValidation("Max-Forwards", "0");
  745. Assert.AreEqual(0, headers.MaxForwards);
  746. }
  747. [TestMethod]
  748. public void MaxForwards_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  749. {
  750. headers.AddWithoutValidation("Max-Forwards", "15,");
  751. Assert.IsNull(headers.GetParsedValues("Max-Forwards"), "Parsed value.");
  752. Assert.AreEqual(1, headers.GetValues("Max-Forwards").Count(), "Store value count");
  753. Assert.AreEqual("15,", headers.GetValues("Max-Forwards").First(), "Store value");
  754. headers.Clear();
  755. headers.AddWithoutValidation("Max-Forwards", "1.0");
  756. Assert.IsNull(headers.GetParsedValues("Max-Forwards"), "Parsed value.");
  757. Assert.AreEqual(1, headers.GetValues("Max-Forwards").Count(), "Store value count");
  758. Assert.AreEqual("1.0", headers.GetValues("Max-Forwards").First(), "Store value");
  759. }
  760. #endregion
  761. #region General headers
  762. [TestMethod]
  763. public void Connection_AddClose_Success()
  764. {
  765. headers.Connection.Add("CLOSE"); // use non-default casing to make sure we do case-insensitive comparison.
  766. Assert.IsTrue(headers.ConnectionClose == true);
  767. Assert.AreEqual(1, headers.Connection.Count);
  768. }
  769. [TestMethod]
  770. public void Connection_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  771. {
  772. Assert.AreEqual(0, headers.Connection.Count, "Collection expected to be empty on first call.");
  773. Assert.IsNull(headers.ConnectionClose, "ConnectionClose should be null by default.");
  774. headers.Connection.Add("custom1");
  775. headers.Connection.Add("custom2");
  776. headers.ConnectionClose = true;
  777. // Connection collection has 2 values plus 'close'
  778. Assert.AreEqual(3, headers.Connection.Count, "Connection.Count");
  779. Assert.AreEqual(3, headers.GetValues("Connection").Count(), "Connection header value count.");
  780. Assert.IsTrue(headers.ConnectionClose == true, "ConnectionClose");
  781. Assert.AreEqual("custom1", headers.Connection.ElementAt(0), "Connection[0]");
  782. Assert.AreEqual("custom2", headers.Connection.ElementAt(1), "Connection[1]");
  783. // Remove 'close' value from store. But leave other 'Connection' values.
  784. headers.ConnectionClose = false;
  785. Assert.IsTrue(headers.ConnectionClose == false, "ConnectionClose == false");
  786. Assert.AreEqual(2, headers.Connection.Count, "Connection.Count");
  787. Assert.AreEqual("custom1", headers.Connection.ElementAt(0), "Connection[0]");
  788. Assert.AreEqual("custom2", headers.Connection.ElementAt(1), "Connection[1]");
  789. headers.ConnectionClose = true;
  790. headers.Connection.Clear();
  791. Assert.IsTrue(headers.ConnectionClose == false,
  792. "ConnectionClose should be modified by Connection.Clear().");
  793. Assert.AreEqual(0, headers.Connection.Count, "Count after Clear().");
  794. IEnumerable<string> dummyArray;
  795. Assert.IsFalse(headers.TryGetValues("Connection", out dummyArray),
  796. "Connection header count after Connection.Clear().");
  797. // Remove 'close' value from store. Since there are no other 'Connection' values, remove whole header.
  798. headers.ConnectionClose = false;
  799. Assert.IsTrue(headers.ConnectionClose == false, "ConnectionClose == false");
  800. Assert.AreEqual(0, headers.Connection.Count, "Connection.Count");
  801. Assert.IsFalse(headers.Contains("Connection"));
  802. headers.ConnectionClose = null;
  803. Assert.IsNull(headers.ConnectionClose, "ConnectionClose");
  804. }
  805. [TestMethod]
  806. public void Connection_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  807. {
  808. headers.AddWithoutValidation("Connection", "custom1, close, custom2, custom3");
  809. // Connection collection has 3 values plus 'close'
  810. Assert.AreEqual(4, headers.Connection.Count, "Connection.Count");
  811. Assert.AreEqual(4, headers.GetValues("Connection").Count(), "Connection header value count.");
  812. Assert.IsTrue(headers.ConnectionClose == true, "ConnectionClose expected to be true.");
  813. Assert.AreEqual("custom1", headers.Connection.ElementAt(0), "Connection[0]");
  814. Assert.AreEqual("close", headers.Connection.ElementAt(1), "Connection[1]");
  815. Assert.AreEqual("custom2", headers.Connection.ElementAt(2), "Connection[2]");
  816. Assert.AreEqual("custom3", headers.Connection.ElementAt(3), "Connection[3]");
  817. headers.Connection.Clear();
  818. Assert.IsNull(headers.ConnectionClose, "ConnectionClose should be modified by Connection.Clear().");
  819. Assert.AreEqual(0, headers.Connection.Count, "Count after Clear().");
  820. IEnumerable<string> dummyArray;
  821. Assert.IsFalse(headers.TryGetValues("Connection", out dummyArray),
  822. "Connection header count after Connection.Clear().");
  823. }
  824. [TestMethod]
  825. [ExpectedException(typeof(FormatException))]
  826. public void Connection_AddInvalidValue_Throw()
  827. {
  828. headers.Connection.Add("this is invalid");
  829. }
  830. [TestMethod]
  831. public void TransferEncoding_AddChunked_Success()
  832. {
  833. // use non-default casing to make sure we do case-insensitive comparison.
  834. headers.TransferEncoding.Add(new TransferCodingHeaderValue("CHUNKED"));
  835. Assert.IsTrue(headers.TransferEncodingChunked == true);
  836. Assert.AreEqual(1, headers.TransferEncoding.Count);
  837. }
  838. [TestMethod]
  839. public void TransferEncoding_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  840. {
  841. Assert.AreEqual(0, headers.TransferEncoding.Count, "TransferEncoding expected to be empty on first call.");
  842. Assert.IsNull(headers.TransferEncodingChunked, "TransferEncodingChunked should be null by default.");
  843. headers.TransferEncoding.Add(new TransferCodingHeaderValue("custom1"));
  844. headers.TransferEncoding.Add(new TransferCodingHeaderValue("custom2"));
  845. headers.TransferEncodingChunked = true;
  846. // Connection collection has 2 values plus 'chunked'
  847. Assert.AreEqual(3, headers.TransferEncoding.Count, "TransferEncoding.Count");
  848. Assert.AreEqual(3, headers.GetValues("Transfer-Encoding").Count(), "Transfer-Encoding header value count.");
  849. Assert.AreEqual(headers.TransferEncodingChunked, true, "TransferEncodingChunked == true");
  850. Assert.AreEqual(new TransferCodingHeaderValue("custom1"), headers.TransferEncoding.ElementAt(0),
  851. "TransferEncoding[0]");
  852. Assert.AreEqual(new TransferCodingHeaderValue("custom2"), headers.TransferEncoding.ElementAt(1),
  853. "TransferEncoding[1]");
  854. // Remove 'chunked' value from store. But leave other 'Transfer-Encoding' values. Note that according to
  855. // the RFC this is not valid, since 'chunked' must always be present. However this check is done
  856. // in the transport handler since the user can add invalid header values anyways.
  857. headers.TransferEncodingChunked = false;
  858. Assert.IsTrue(headers.TransferEncodingChunked == false, "TransferEncodingChunked == false");
  859. Assert.AreEqual(2, headers.TransferEncoding.Count, "TransferEncoding.Count");
  860. Assert.AreEqual(new TransferCodingHeaderValue("custom1"), headers.TransferEncoding.ElementAt(0),
  861. "TransferEncoding[0]");
  862. Assert.AreEqual(new TransferCodingHeaderValue("custom2"), headers.TransferEncoding.ElementAt(1),
  863. "TransferEncoding[1]");
  864. headers.TransferEncodingChunked = true;
  865. headers.TransferEncoding.Clear();
  866. Assert.IsTrue(headers.TransferEncodingChunked == false,
  867. "TransferEncodingChunked should be modified by TransferEncoding.Clear().");
  868. Assert.AreEqual(0, headers.TransferEncoding.Count, "Count after Clear().");
  869. Assert.IsFalse(headers.Contains("Transfer-Encoding"));
  870. // Remove 'chunked' value from store. Since there are no other 'Transfer-Encoding' values, remove whole
  871. // header.
  872. headers.TransferEncodingChunked = false;
  873. Assert.IsTrue(headers.TransferEncodingChunked == false, "TransferEncodingChunked == false");
  874. Assert.AreEqual(0, headers.TransferEncoding.Count, "TransferEncoding.Count");
  875. Assert.IsFalse(headers.Contains("Transfer-Encoding"));
  876. headers.TransferEncodingChunked = null;
  877. Assert.IsNull(headers.TransferEncodingChunked, "TransferEncodingChunked");
  878. }
  879. [TestMethod]
  880. public void TransferEncoding_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  881. {
  882. headers.AddWithoutValidation("Transfer-Encoding", " , custom1, , custom2, custom3, chunked ,");
  883. // Connection collection has 3 values plus 'chunked'
  884. Assert.AreEqual(4, headers.TransferEncoding.Count, "TransferEncoding.Count");
  885. Assert.AreEqual(4, headers.GetValues("Transfer-Encoding").Count(),
  886. "Transfer-Encoding header value count.");
  887. Assert.IsTrue(headers.TransferEncodingChunked == true, "TransferEncodingChunked expected to be true.");
  888. Assert.AreEqual(new TransferCodingHeaderValue("custom1"), headers.TransferEncoding.ElementAt(0),
  889. "TransferEncoding[0]");
  890. Assert.AreEqual(new TransferCodingHeaderValue("custom2"), headers.TransferEncoding.ElementAt(1),
  891. "TransferEncoding[1]");
  892. Assert.AreEqual(new TransferCodingHeaderValue("custom3"), headers.TransferEncoding.ElementAt(2),
  893. "TransferEncoding[2]");
  894. headers.TransferEncoding.Clear();
  895. Assert.IsNull(headers.TransferEncodingChunked,
  896. "TransferEncodingChunked should be modified by TransferEncoding.Clear().");
  897. Assert.AreEqual(0, headers.TransferEncoding.Count, "Count after Clear().");
  898. Assert.IsFalse(headers.Contains("Transfer-Encoding"),
  899. "Transfer-Encoding header after TransferEncoding.Clear().");
  900. }
  901. [TestMethod]
  902. public void TransferEncoding_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  903. {
  904. headers.AddWithoutValidation("Transfer-Encoding", "custom会");
  905. Assert.IsNull(headers.GetParsedValues("Transfer-Encoding"), "Parsed value.");
  906. Assert.AreEqual(1, headers.GetValues("Transfer-Encoding").Count(), "Store value count");
  907. Assert.AreEqual("custom会", headers.GetValues("Transfer-Encoding").First(), "Store value");
  908. headers.Clear();
  909. headers.AddWithoutValidation("Transfer-Encoding", "custom1 custom2");
  910. Assert.IsNull(headers.GetParsedValues("Transfer-Encoding"), "Parsed value.");
  911. Assert.AreEqual(1, headers.GetValues("Transfer-Encoding").Count(), "Store value count");
  912. Assert.AreEqual("custom1 custom2", headers.GetValues("Transfer-Encoding").First(), "Store value");
  913. headers.Clear();
  914. headers.AddWithoutValidation("Transfer-Encoding", "");
  915. Assert.IsFalse(headers.Contains("Transfer-Encoding"), "'Transfer-Encoding' header should not be added if it just has empty values.");
  916. }
  917. [TestMethod]
  918. public void Upgrade_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  919. {
  920. Assert.AreEqual(0, headers.Upgrade.Count, "Upgrade expected to be empty on first call.");
  921. headers.Upgrade.Add(new ProductHeaderValue("custom1"));
  922. headers.Upgrade.Add(new ProductHeaderValue("custom2", "1.1"));
  923. Assert.AreEqual(2, headers.Upgrade.Count, "Upgrade.Count");
  924. Assert.AreEqual(2, headers.GetValues("Upgrade").Count(), "Upgrade header value count.");
  925. Assert.AreEqual(new ProductHeaderValue("custom1"), headers.Upgrade.ElementAt(0), "Upgrade[0]");
  926. Assert.AreEqual(new ProductHeaderValue("custom2", "1.1"), headers.Upgrade.ElementAt(1), "Upgrade[1]");
  927. headers.Upgrade.Clear();
  928. Assert.AreEqual(0, headers.Upgrade.Count, "Count after Clear().");
  929. Assert.IsFalse(headers.Contains("Upgrade"), "Upgrade header should be removed after calling Clear().");
  930. }
  931. [TestMethod]
  932. public void Upgrade_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  933. {
  934. headers.AddWithoutValidation("Upgrade", " , custom1 / 1.0, , custom2, custom3/2.0,");
  935. Assert.AreEqual(3, headers.Upgrade.Count, "Upgrade.Count");
  936. Assert.AreEqual(3, headers.GetValues("Upgrade").Count(),
  937. "Upgrade header value count.");
  938. Assert.AreEqual(new ProductHeaderValue("custom1", "1.0"), headers.Upgrade.ElementAt(0), "Upgrade[0]");
  939. Assert.AreEqual(new ProductHeaderValue("custom2"), headers.Upgrade.ElementAt(1), "Upgrade[1]");
  940. Assert.AreEqual(new ProductHeaderValue("custom3", "2.0"), headers.Upgrade.ElementAt(2), "Upgrade[2]");
  941. headers.Upgrade.Clear();
  942. Assert.AreEqual(0, headers.Upgrade.Count, "Count after Clear().");
  943. Assert.IsFalse(headers.Contains("Upgrade"), "Upgrade header should be removed after calling Clear().");
  944. }
  945. [TestMethod]
  946. public void Upgrade_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  947. {
  948. headers.AddWithoutValidation("Upgrade", "custom会");
  949. Assert.IsNull(headers.GetParsedValues("Upgrade"), "Parsed value.");
  950. Assert.AreEqual(1, headers.GetValues("Upgrade").Count(), "Store value count");
  951. Assert.AreEqual("custom会", headers.GetValues("Upgrade").First(), "Store value");
  952. headers.Clear();
  953. headers.AddWithoutValidation("Upgrade", "custom1 custom2");
  954. Assert.IsNull(headers.GetParsedValues("Upgrade"), "Parsed value.");
  955. Assert.AreEqual(1, headers.GetValues("Upgrade").Count(), "Store value count");
  956. Assert.AreEqual("custom1 custom2", headers.GetValues("Upgrade").First(), "Store value");
  957. }
  958. [TestMethod]
  959. public void Date_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  960. {
  961. Assert.IsNull(headers.Date, "Host should be null by default.");
  962. DateTimeOffset expected = DateTimeOffset.Now;
  963. headers.Date = expected;
  964. Assert.AreEqual(expected, headers.Date);
  965. headers.Date = null;
  966. Assert.IsNull(headers.Date, "Date should be null after setting it to null.");
  967. Assert.IsFalse(headers.Contains("Date"),
  968. "Header store should not contain a header 'Date' after setting it to null.");
  969. // Make sure the header gets serialized correctly
  970. headers.Date = (new DateTimeOffset(1994, 11, 6, 8, 49, 37, TimeSpan.Zero));
  971. Assert.AreEqual("Sun, 06 Nov 1994 08:49:37 GMT", headers.GetValues("Date").First(), "Serialized header");
  972. }
  973. [TestMethod]
  974. public void Date_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  975. {
  976. headers.AddWithoutValidation("Date", " Sun, 06 Nov 1994 08:49:37 GMT ");
  977. Assert.AreEqual(new DateTimeOffset(1994, 11, 6, 8, 49, 37, TimeSpan.Zero), headers.Date);
  978. headers.Clear();
  979. headers.AddWithoutValidation("Date", "Sun, 06 Nov 1994 08:49:37 GMT");
  980. Assert.AreEqual(new DateTimeOffset(1994, 11, 6, 8, 49, 37, TimeSpan.Zero), headers.Date);
  981. }
  982. [TestMethod]
  983. public void Date_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  984. {
  985. headers.AddWithoutValidation("Date", " Sun, 06 Nov 1994 08:49:37 GMT ,");
  986. Assert.IsNull(headers.GetParsedValues("Date"), "Parsed value.");
  987. Assert.AreEqual(1, headers.GetValues("Date").Count(), "Store value count");
  988. Assert.AreEqual(" Sun, 06 Nov 1994 08:49:37 GMT ,", headers.GetValues("Date").First(), "Store value");
  989. headers.Clear();
  990. headers.AddWithoutValidation("Date", " Sun, 06 Nov ");
  991. Assert.IsNull(headers.GetParsedValues("Date"), "Parsed value.");
  992. Assert.AreEqual(1, headers.GetValues("Date").Count(), "Store value count");
  993. Assert.AreEqual(" Sun, 06 Nov ", headers.GetValues("Date").First(), "Store value");
  994. }
  995. [TestMethod]
  996. public void Via_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  997. {
  998. Assert.AreEqual(0, headers.Via.Count, "Collection expected to be empty on first call.");
  999. headers.Via.Add(new ViaHeaderValue("x11", "host"));
  1000. headers.Via.Add(new ViaHeaderValue("1.1", "example.com:8080", "HTTP", "(comment)"));
  1001. Assert.AreEqual(2, headers.Via.Count, "Count");
  1002. Assert.AreEqual(new ViaHeaderValue("x11", "host"), headers.Via.ElementAt(0), "Via[0]");
  1003. Assert.AreEqual(new ViaHeaderValue("1.1", "example.com:8080", "HTTP", "(comment)"),
  1004. headers.Via.ElementAt(1), "Via[1]");
  1005. headers.Via.Clear();
  1006. Assert.AreEqual(0, headers.Via.Count, "Count after Clear().");
  1007. }
  1008. [TestMethod]
  1009. public void Via_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  1010. {
  1011. headers.AddWithoutValidation("Via", ", 1.1 host, WS/1.0 [::1],X/11 192.168.0.1 (c(comment)) ");
  1012. Assert.AreEqual(new ViaHeaderValue("1.1", "host"), headers.Via.ElementAt(0), "Via[0]");
  1013. Assert.AreEqual(new ViaHeaderValue("1.0", "[::1]", "WS"), headers.Via.ElementAt(1), "Via[1]");
  1014. Assert.AreEqual(new ViaHeaderValue("11", "192.168.0.1", "X", "(c(comment))"), headers.Via.ElementAt(2),
  1015. "Via[2]");
  1016. headers.Via.Clear();
  1017. headers.AddWithoutValidation("Via", "");
  1018. Assert.AreEqual(0, headers.Via.Count, "Count after Clear().");
  1019. Assert.IsFalse(headers.Contains("Via"));
  1020. }
  1021. [TestMethod]
  1022. public void Via_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  1023. {
  1024. headers.AddWithoutValidation("Via", "1.1 host1 1.1 host2"); // no separator
  1025. Assert.AreEqual(0, headers.Via.Count, "Via.Count");
  1026. Assert.AreEqual(1, headers.GetValues("Via").Count(), "Via.Count");
  1027. Assert.AreEqual("1.1 host1 1.1 host2", headers.GetValues("Via").First(), "Via value");
  1028. headers.Clear();
  1029. headers.AddWithoutValidation("Via", "X/11 host/1");
  1030. Assert.AreEqual(0, headers.Via.Count, "Via.Count");
  1031. Assert.AreEqual(1, headers.GetValues("Via").Count(), "Via.Count");
  1032. Assert.AreEqual("X/11 host/1", headers.GetValues("Via").First(), "Via value");
  1033. }
  1034. [TestMethod]
  1035. public void Warning_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  1036. {
  1037. Assert.AreEqual(0, headers.Warning.Count, "Collection expected to be empty on first call.");
  1038. headers.Warning.Add(new WarningHeaderValue(199, "microsoft.com", "\"Miscellaneous warning\""));
  1039. headers.Warning.Add(new WarningHeaderValue(113, "example.com", "\"Heuristic expiration\""));
  1040. Assert.AreEqual(2, headers.Warning.Count, "Count");
  1041. Assert.AreEqual(new WarningHeaderValue(199, "microsoft.com", "\"Miscellaneous warning\""),
  1042. headers.Warning.ElementAt(0), "Warning[0]");
  1043. Assert.AreEqual(new WarningHeaderValue(113, "example.com", "\"Heuristic expiration\""),
  1044. headers.Warning.ElementAt(1), "Warning[1]");
  1045. headers.Warning.Clear();
  1046. Assert.AreEqual(0, headers.Warning.Count, "Count after Clear().");
  1047. }
  1048. [TestMethod]
  1049. public void Warning_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  1050. {
  1051. headers.AddWithoutValidation("Warning",
  1052. "112 example.com \"Disconnected operation\", 111 example.org \"Revalidation failed\"");
  1053. Assert.AreEqual(new WarningHeaderValue(112, "example.com", "\"Disconnected operation\""),
  1054. headers.Warning.ElementAt(0), "Warning[0]");
  1055. Assert.AreEqual(new WarningHeaderValue(111, "example.org", "\"Revalidation failed\""),
  1056. headers.Warning.ElementAt(1), "Warning[1]");
  1057. headers.Warning.Clear();
  1058. headers.AddWithoutValidation("Warning", "");
  1059. Assert.AreEqual(0, headers.Warning.Count, "Count after Clear().");
  1060. Assert.IsFalse(headers.Contains("Warning"));
  1061. }
  1062. [TestMethod]
  1063. public void Warning_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  1064. {
  1065. headers.AddWithoutValidation("Warning", "123 host1 \"\" 456 host2 \"\""); // no separator
  1066. Assert.AreEqual(0, headers.Warning.Count, "Warning.Count");
  1067. Assert.AreEqual(1, headers.GetValues("Warning").Count(), "Warning.Count");
  1068. Assert.AreEqual("123 host1 \"\" 456 host2 \"\"", headers.GetValues("Warning").First(), "Warning value");
  1069. headers.Clear();
  1070. headers.AddWithoutValidation("Warning", "123 host1\"text\"");
  1071. Assert.AreEqual(0, headers.Warning.Count, "Warning.Count");
  1072. Assert.AreEqual(1, headers.GetValues("Warning").Count(), "Warning.Count");
  1073. Assert.AreEqual("123 host1\"text\"", headers.GetValues("Warning").First(), "Warning value");
  1074. }
  1075. [TestMethod]
  1076. public void CacheControl_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  1077. {
  1078. Assert.IsNull(headers.CacheControl, "CacheControl should be null by default.");
  1079. CacheControlHeaderValue value = new CacheControlHeaderValue();
  1080. value.NoCache = true;
  1081. value.NoCacheHeaders.Add("token1");
  1082. value.NoCacheHeaders.Add("token2");
  1083. value.MustRevalidate = true;
  1084. value.SharedMaxAge = new TimeSpan(1, 2, 3);
  1085. headers.CacheControl = value;
  1086. Assert.AreEqual(value, headers.CacheControl);
  1087. headers.CacheControl = null;
  1088. Assert.IsNull(headers.CacheControl, "CacheControl should be null after setting it to null.");
  1089. Assert.IsFalse(headers.Contains("Cache-Control"),
  1090. "Header store should not contain a header 'Cache-Control' after setting it to null.");
  1091. }
  1092. [TestMethod]
  1093. public void CacheControl_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  1094. {
  1095. headers.AddWithoutValidation("Cache-Control", "no-cache=\"token1, token2\", must-revalidate, max-age=3");
  1096. headers.Add("Cache-Control", "");
  1097. headers.Add("Cache-Control", "public, s-maxage=15");
  1098. headers.AddWithoutValidation("Cache-Control", "");
  1099. CacheControlHeaderValue value = new CacheControlHeaderValue();
  1100. value.NoCache = true;
  1101. value.NoCacheHeaders.Add("token1");
  1102. value.NoCacheHeaders.Add("token2");
  1103. value.MustRevalidate = true;
  1104. value.MaxAge = new TimeSpan(0, 0, 3);
  1105. value.Public = true;
  1106. value.SharedMaxAge = new TimeSpan(0, 0, 15);
  1107. Assert.AreEqual(value, headers.CacheControl);
  1108. }
  1109. [TestMethod]
  1110. public void Trailer_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  1111. {
  1112. Assert.AreEqual(0, headers.Trailer.Count, "Collection expected to be empty on first call.");
  1113. headers.Trailer.Add("custom1");
  1114. headers.Trailer.Add("custom2");
  1115. Assert.AreEqual(2, headers.Trailer.Count, "Trailer.Count");
  1116. Assert.AreEqual(2, headers.GetValues("Trailer").Count(), "Trailer header value count.");
  1117. Assert.AreEqual("custom1", headers.Trailer.ElementAt(0), "Trailer[0]");
  1118. Assert.AreEqual("custom2", headers.Trailer.ElementAt(1), "Trailer[1]");
  1119. headers.Trailer.Clear();
  1120. Assert.AreEqual(0, headers.Trailer.Count, "Count after Clear().");
  1121. Assert.IsFalse(headers.Contains("Trailer"),
  1122. "There should be no Trailer header after calling Clear().");
  1123. }
  1124. [TestMethod]
  1125. public void Trailer_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  1126. {
  1127. headers.AddWithoutValidation("Trailer", ",custom1, custom2, custom3,");
  1128. Assert.AreEqual(3, headers.Trailer.Count, "Trailer.Count");
  1129. Assert.AreEqual(3, headers.GetValues("Trailer").Count(), "Trailer header value count.");
  1130. Assert.AreEqual("custom1", headers.Trailer.ElementAt(0), "Trailer[0]");
  1131. Assert.AreEqual("custom2", headers.Trailer.ElementAt(1), "Trailer[1]");
  1132. Assert.AreEqual("custom3", headers.Trailer.ElementAt(2), "Trailer[2]");
  1133. headers.Trailer.Clear();
  1134. Assert.AreEqual(0, headers.Trailer.Count, "Count after Clear().");
  1135. Assert.IsFalse(headers.Contains("Trailer"),
  1136. "There should be no Trailer header after calling Clear().");
  1137. }
  1138. [TestMethod]
  1139. public void Trailer_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  1140. {
  1141. headers.AddWithoutValidation("Trailer", "custom1 custom2"); // no separator
  1142. Assert.AreEqual(0, headers.Trailer.Count, "Trailer.Count");
  1143. Assert.AreEqual(1, headers.GetValues("Trailer").Count(), "Trailer.Count");
  1144. Assert.AreEqual("custom1 custom2", headers.GetValues("Trailer").First(), "Trailer value");
  1145. }
  1146. [TestMethod]
  1147. public void Pragma_ReadAndWriteProperty_ValueMatchesPriorSetValue()
  1148. {
  1149. Assert.AreEqual(0, headers.Pragma.Count, "Collection expected to be empty on first call.");
  1150. headers.Pragma.Add(new NameValueHeaderValue("custom1", "value1"));
  1151. headers.Pragma.Add(new NameValueHeaderValue("custom2"));
  1152. Assert.AreEqual(2, headers.Pragma.Count, "Pragma.Count");
  1153. Assert.AreEqual(2, headers.GetValues("Pragma").Count(), "Pragma header value count.");
  1154. Assert.AreEqual(new NameValueHeaderValue("custom1", "value1"), headers.Pragma.ElementAt(0), "Pragma[0]");
  1155. Assert.AreEqual(new NameValueHeaderValue("custom2"), headers.Pragma.ElementAt(1), "Pragma[1]");
  1156. headers.Pragma.Clear();
  1157. Assert.AreEqual(0, headers.Pragma.Count, "Count after Clear().");
  1158. Assert.IsFalse(headers.Contains("Pragma"),
  1159. "There should be no Pragma header after calling Clear().");
  1160. }
  1161. [TestMethod]
  1162. public void Pragma_UseAddMethod_AddedValueCanBeRetrievedUsingProperty()
  1163. {
  1164. headers.AddWithoutValidation("Pragma", ",custom1=value1, custom2, custom3=value3,");
  1165. Assert.AreEqual(3, headers.Pragma.Count, "Pragma.Count");
  1166. Assert.AreEqual(3, headers.GetValues("Pragma").Count(), "Pragma header value count.");
  1167. Assert.AreEqual(new NameValueHeaderValue("custom1", "value1"), headers.Pragma.ElementAt(0), "Pragma[0]");
  1168. Assert.AreEqual(new NameValueHeaderValue("custom2"), headers.Pragma.ElementAt(1), "Pragma[1]");
  1169. Assert.AreEqual(new NameValueHeaderValue("custom3", "value3"), headers.Pragma.ElementAt(2), "Pragma[2]");
  1170. headers.Pragma.Clear();
  1171. Assert.AreEqual(0, headers.Pragma.Count, "Count after Clear().");
  1172. Assert.IsFalse(headers.Contains("Pragma"),
  1173. "There should be no Pragma header after calling Clear().");
  1174. }
  1175. [TestMethod]
  1176. public void Pragma_UseAddMethodWithInvalidValue_InvalidValueRecognized()
  1177. {
  1178. headers.AddWithoutValidation("Pragma", "custom1, custom2=");
  1179. Assert.AreEqual(0, headers.Pragma.Count, "Pragma.Count");
  1180. Assert.AreEqual(1, headers.GetValues("Pragma").Count(), "Pragma.Count");
  1181. Assert.AreEqual("custom1, custom2=", headers.GetValues("Pragma").First(), "Pragma value");
  1182. }
  1183. #endregion
  1184. [TestMethod]
  1185. public void ToString_SeveralRequestHeaders_Success()
  1186. {
  1187. HttpRequestMessage request = new HttpRequestMessage();
  1188. string expected = string.Empty;
  1189. request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
  1190. request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("*/xml"));
  1191. expected += HttpKnownHeaderNames.Accept + ": application/xml, */xml\r\n";
  1192. request.Headers.Authorization = new AuthenticationHeaderValue("Basic");
  1193. expected += HttpKnownHeaderNames.Authorization + ": Basic\r\n";
  1194. request.Headers.ExpectContinue = true;
  1195. expected += HttpKnownHeaderNames.Expect + ": 100-continue\r\n";
  1196. request.Headers.TransferEncodingChunked = true;
  1197. expected += HttpKnownHeaderNames.TransferEncoding + ": chunked\r\n";
  1198. Assert.AreEqual(expected, request.Headers.ToString());
  1199. }
  1200. [TestMethod]
  1201. public void InvalidHeaders_AddContentAndResponseHeaders_Throw()
  1202. {
  1203. // Try adding response and content headers. Use different casing to make sure case-insensitive comparison
  1204. // is used.
  1205. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Accept-Ranges", "v"), "Accept-Ranges");
  1206. ExceptionAssert.ThrowsInvalidOperation(() => headers.AddWithoutValidation("age", "v"), "age");
  1207. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("ETag", "v"), "ETag");
  1208. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Location", "v"), "Location");
  1209. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Proxy-Authenticate", "v"), "Proxy-Authenticate");
  1210. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Retry-After", "v"), "Retry-After");
  1211. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Server", "v"), "Server");
  1212. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Vary", "v"), "Vary");
  1213. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("WWW-Authenticate", "v"), "WWW-Authenticate");
  1214. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Allow", "v"), "Allow");
  1215. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Content-Encoding", "v"), "Content-Encoding");
  1216. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Content-Language", "v"), "Content-Language");
  1217. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("content-length", "v"), "content-length");
  1218. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Content-Location", "v"), "Content-Location");
  1219. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Content-MD5", "v"), "Content-MD5");
  1220. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Content-Range", "v"), "Content-Range");
  1221. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("CONTENT-TYPE", "v"), "CONTENT-TYPE");
  1222. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Expires", "v"), "Expires");
  1223. ExceptionAssert.ThrowsInvalidOperation(() => headers.Add("Last-Modified", "v"), "Last-Modified");
  1224. }
  1225. }
  1226. }