PageRenderTime 64ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/test/System.Net.Http.Formatting.Test.Unit/Formatting/Parsers/HttpStatusLineParserTests.cs

https://bitbucket.org/mdavid/aspnetwebstack
C# | 285 lines | 239 code | 46 blank | 0 comment | 11 complexity | 578a0b518688f3f6b87475c2b622b758 MD5 | raw file
  1. using System.Collections.Generic;
  2. using System.Net.Http.Formatting.DataSets;
  3. using System.Text;
  4. using Microsoft.TestCommon;
  5. using Xunit;
  6. using Xunit.Extensions;
  7. using Assert = Microsoft.TestCommon.AssertEx;
  8. namespace System.Net.Http.Formatting.Parsers
  9. {
  10. public class HttpStatusLineParserTests
  11. {
  12. [Fact]
  13. [Trait("Description", "HttpStatusLineParser is internal class")]
  14. public void TypeIsCorrect()
  15. {
  16. Assert.Type.HasProperties<HttpStatusLineParser>(TypeAssert.TypeProperties.IsClass);
  17. }
  18. internal static byte[] CreateBuffer(string version, string statusCode, string reasonPhrase)
  19. {
  20. return CreateBuffer(version, statusCode, reasonPhrase, false);
  21. }
  22. private static byte[] CreateBuffer(string version, string statusCode, string reasonPhrase, bool withLws)
  23. {
  24. const string SP = " ";
  25. const string HTAB = "\t";
  26. const string CRLF = "\r\n";
  27. string lws = SP;
  28. if (withLws)
  29. {
  30. lws = SP + SP + HTAB + SP;
  31. }
  32. string statusLine = String.Format("{0}{1}{2}{3}{4}{5}", version, lws, statusCode, lws, reasonPhrase, CRLF);
  33. return Encoding.UTF8.GetBytes(statusLine);
  34. }
  35. private static ParserState ParseBufferInSteps(HttpStatusLineParser parser, byte[] buffer, int readsize, out int totalBytesConsumed)
  36. {
  37. ParserState state = ParserState.Invalid;
  38. totalBytesConsumed = 0;
  39. while (totalBytesConsumed <= buffer.Length)
  40. {
  41. int size = Math.Min(buffer.Length - totalBytesConsumed, readsize);
  42. byte[] parseBuffer = new byte[size];
  43. Buffer.BlockCopy(buffer, totalBytesConsumed, parseBuffer, 0, size);
  44. int bytesConsumed = 0;
  45. state = parser.ParseBuffer(parseBuffer, parseBuffer.Length, ref bytesConsumed);
  46. totalBytesConsumed += bytesConsumed;
  47. if (state != ParserState.NeedMoreData)
  48. {
  49. return state;
  50. }
  51. }
  52. return state;
  53. }
  54. private static void ValidateResult(HttpUnsortedResponse statusLine, Version version, HttpStatusCode statusCode, string reasonPhrase)
  55. {
  56. Assert.Equal(version, statusLine.Version);
  57. Assert.Equal(statusCode, statusLine.StatusCode);
  58. Assert.Equal(reasonPhrase, statusLine.ReasonPhrase);
  59. }
  60. [Fact]
  61. [Trait("Description", "HttpStatusLineParser constructor throws on invalid arguments")]
  62. public void HttpStatusLineParserConstructorTest()
  63. {
  64. HttpUnsortedResponse statusLine = new HttpUnsortedResponse();
  65. Assert.NotNull(statusLine);
  66. Assert.ThrowsArgumentGreaterThanOrEqualTo(() => new HttpStatusLineParser(statusLine, ParserData.MinStatusLineSize - 1),
  67. "maxStatusLineSize", ParserData.MinStatusLineSize.ToString(), ParserData.MinStatusLineSize - 1);
  68. HttpStatusLineParser parser = new HttpStatusLineParser(statusLine, ParserData.MinStatusLineSize);
  69. Assert.NotNull(parser);
  70. Assert.ThrowsArgumentNull(() => { new HttpStatusLineParser(null, ParserData.MinStatusLineSize); }, "httpResponse");
  71. }
  72. [Fact]
  73. [Trait("Description", "HttpStatusLineParser.ParseBuffer throws on null buffer.")]
  74. public void StatusLineParserNullBuffer()
  75. {
  76. HttpUnsortedResponse statusLine = new HttpUnsortedResponse();
  77. HttpStatusLineParser parser = new HttpStatusLineParser(statusLine, ParserData.MinStatusLineSize);
  78. Assert.NotNull(parser);
  79. int bytesConsumed = 0;
  80. Assert.ThrowsArgumentNull(() => { parser.ParseBuffer(null, 0, ref bytesConsumed); }, "buffer");
  81. }
  82. [Fact]
  83. [Trait("Description", "HttpStatusLineParser.ParseBuffer parses minimum requestline.")]
  84. public void StatusLineParserMinimumBuffer()
  85. {
  86. byte[] data = CreateBuffer("HTTP/1.1", "200", "");
  87. HttpUnsortedResponse statusLine = new HttpUnsortedResponse();
  88. HttpStatusLineParser parser = new HttpStatusLineParser(statusLine, ParserData.MinStatusLineSize);
  89. Assert.NotNull(parser);
  90. int bytesConsumed = 0;
  91. ParserState state = parser.ParseBuffer(data, data.Length, ref bytesConsumed);
  92. Assert.Equal(ParserState.Done, state);
  93. Assert.Equal(data.Length, bytesConsumed);
  94. ValidateResult(statusLine, new Version("1.1"), HttpStatusCode.OK, "");
  95. }
  96. [Fact]
  97. [Trait("Description", "HttpStatusLineParser.ParseBuffer rejects LWS requestline.")]
  98. public void StatusLineParserRejectsLws()
  99. {
  100. byte[] data = CreateBuffer("HTTP/1.1", "200", "Reason", true);
  101. for (var cnt = 1; cnt <= data.Length; cnt++)
  102. {
  103. HttpUnsortedResponse statusLine = new HttpUnsortedResponse();
  104. HttpStatusLineParser parser = new HttpStatusLineParser(statusLine, data.Length);
  105. Assert.NotNull(parser);
  106. int totalBytesConsumed = 0;
  107. ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed);
  108. Assert.Equal(ParserState.Invalid, state);
  109. }
  110. }
  111. [Fact]
  112. [Trait("Description", "HttpStatusLineParser.ParseBuffer parses standard status codes.")]
  113. public void StatusLineParserAcceptsStandardStatusCodes()
  114. {
  115. foreach (HttpStatusCode status in HttpUnitTestDataSets.AllHttpStatusCodes)
  116. {
  117. byte[] data = CreateBuffer("HTTP/1.1", ((int)status).ToString(), "Reason");
  118. for (var cnt = 1; cnt <= data.Length; cnt++)
  119. {
  120. HttpUnsortedResponse statusLine = new HttpUnsortedResponse();
  121. HttpStatusLineParser parser = new HttpStatusLineParser(statusLine, data.Length);
  122. Assert.NotNull(parser);
  123. int totalBytesConsumed = 0;
  124. ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed);
  125. Assert.Equal(ParserState.Done, state);
  126. Assert.Equal(data.Length, totalBytesConsumed);
  127. ValidateResult(statusLine, new Version("1.1"), status, "Reason");
  128. }
  129. }
  130. }
  131. [Fact]
  132. [Trait("Description", "HttpStatusLineParser.ParseBuffer parses custom status codes.")]
  133. public void StatusLineParserAcceptsCustomStatusCodes()
  134. {
  135. foreach (HttpStatusCode status in HttpUnitTestDataSets.CustomHttpStatusCodes)
  136. {
  137. byte[] data = CreateBuffer("HTTP/1.1", ((int)status).ToString(), "Reason");
  138. for (var cnt = 1; cnt <= data.Length; cnt++)
  139. {
  140. HttpUnsortedResponse statusLine = new HttpUnsortedResponse();
  141. HttpStatusLineParser parser = new HttpStatusLineParser(statusLine, data.Length);
  142. Assert.NotNull(parser);
  143. int totalBytesConsumed = 0;
  144. ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed);
  145. Assert.Equal(ParserState.Done, state);
  146. Assert.Equal(data.Length, totalBytesConsumed);
  147. ValidateResult(statusLine, new Version("1.1"), status, "Reason");
  148. }
  149. }
  150. }
  151. [Fact]
  152. [Trait("Description", "HttpStatusLineParser.ParseBuffer rejects invalid status codes")]
  153. public void StatusLineParserRejectsInvalidStatusCodes()
  154. {
  155. foreach (string invalidStatus in ParserData.InvalidStatusCodes)
  156. {
  157. byte[] data = CreateBuffer("HTTP/1.1", invalidStatus, "Reason");
  158. for (var cnt = 1; cnt <= data.Length; cnt++)
  159. {
  160. HttpUnsortedResponse statusLine = new HttpUnsortedResponse();
  161. HttpStatusLineParser parser = new HttpStatusLineParser(statusLine, 256);
  162. Assert.NotNull(parser);
  163. int totalBytesConsumed = 0;
  164. ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed);
  165. Assert.Equal(ParserState.Invalid, state);
  166. }
  167. }
  168. }
  169. public static IEnumerable<object[]> ValidReasonPhrases
  170. {
  171. get
  172. {
  173. yield return new object[] { "" };
  174. yield return new object[] { "Ok" };
  175. yield return new object[] { "public Server Error" };
  176. yield return new object[] { "r e a s o n" };
  177. yield return new object[] { "reason " };
  178. yield return new object[] { " reason " };
  179. }
  180. }
  181. [Theory]
  182. [PropertyData("ValidReasonPhrases")]
  183. [Trait("Description", "HttpStatusLineParser.ParseBuffer accepts valid reason phrase.")]
  184. public void StatusLineParserAcceptsValidReasonPhrase(string validReasonPhrase)
  185. {
  186. byte[] data = CreateBuffer("HTTP/1.1", "200", validReasonPhrase);
  187. for (var cnt = 1; cnt <= data.Length; cnt++)
  188. {
  189. HttpUnsortedResponse statusLine = new HttpUnsortedResponse();
  190. HttpStatusLineParser parser = new HttpStatusLineParser(statusLine, 256);
  191. Assert.NotNull(parser);
  192. int totalBytesConsumed = 0;
  193. ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed);
  194. ValidateResult(statusLine, new Version("1.1"), HttpStatusCode.OK, validReasonPhrase);
  195. }
  196. }
  197. public static IEnumerable<object[]> Versions
  198. {
  199. get { return ParserData.Versions; }
  200. }
  201. [Theory]
  202. [PropertyData("Versions")]
  203. [Trait("Description", "HttpStatusLineParser.ParseBuffer accepts valid versions.")]
  204. public void StatusLineParserAcceptsValidVersion(Version version)
  205. {
  206. byte[] data = CreateBuffer(String.Format("HTTP/{0}", version.ToString(2)), "200", "Reason");
  207. for (var cnt = 1; cnt <= data.Length; cnt++)
  208. {
  209. HttpUnsortedResponse statusLine = new HttpUnsortedResponse();
  210. HttpStatusLineParser parser = new HttpStatusLineParser(statusLine, 256);
  211. Assert.NotNull(parser);
  212. int totalBytesConsumed = 0;
  213. ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed);
  214. Assert.Equal(data.Length, totalBytesConsumed);
  215. ValidateResult(statusLine, version, HttpStatusCode.OK, "Reason");
  216. }
  217. }
  218. public static IEnumerable<object[]> InvalidVersions
  219. {
  220. get { return ParserData.InvalidVersions; }
  221. }
  222. [Theory]
  223. [PropertyData("InvalidVersions")]
  224. [Trait("Description", "HttpStatusLineParser.ParseBuffer rejects invalid protocol version.")]
  225. public void StatusLineParserRejectsInvalidVersion(string invalidVersion)
  226. {
  227. byte[] data = CreateBuffer(invalidVersion, "200", "Reason");
  228. for (var cnt = 1; cnt <= data.Length; cnt++)
  229. {
  230. HttpUnsortedResponse statusLine = new HttpUnsortedResponse();
  231. HttpStatusLineParser parser = new HttpStatusLineParser(statusLine, 256);
  232. Assert.NotNull(parser);
  233. int totalBytesConsumed = 0;
  234. ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed);
  235. Assert.Equal(ParserState.Invalid, state);
  236. }
  237. }
  238. }
  239. }