|
6 | 6 | using System.IO.Pipelines; |
7 | 7 | using System.Text; |
8 | 8 | using Microsoft.AspNetCore.Connections; |
| 9 | +using Microsoft.AspNetCore.Http; |
9 | 10 | using Microsoft.AspNetCore.Http.Features; |
10 | 11 | using Microsoft.AspNetCore.Server.Kestrel.Core; |
11 | 12 | using Microsoft.AspNetCore.Server.Kestrel.Core.Internal; |
@@ -516,6 +517,55 @@ public void AuthorityForms(string rawTarget, string path, string query) |
516 | 517 | DifferentFormsWorkTogether(); |
517 | 518 | } |
518 | 519 |
|
| 520 | + public static IEnumerable<object[]> GetCrLfAndMethodCombinations() |
| 521 | + { |
| 522 | + // HTTP methods to test |
| 523 | + var methods = new string[] { |
| 524 | + HttpMethods.Connect, |
| 525 | + HttpMethods.Delete, |
| 526 | + HttpMethods.Get, |
| 527 | + HttpMethods.Head, |
| 528 | + HttpMethods.Options, |
| 529 | + HttpMethods.Patch, |
| 530 | + HttpMethods.Post, |
| 531 | + HttpMethods.Put, |
| 532 | + HttpMethods.Trace |
| 533 | + }; |
| 534 | + |
| 535 | + // Prefixes to test |
| 536 | + var crLfPrefixes = new string[] { |
| 537 | + "\r", |
| 538 | + "\n", |
| 539 | + "\r\r\r\r\r", |
| 540 | + "\r\n", |
| 541 | + "\n\r" |
| 542 | + }; |
| 543 | + |
| 544 | + foreach (var method in methods) |
| 545 | + { |
| 546 | + foreach (var prefix in crLfPrefixes) |
| 547 | + { |
| 548 | + yield return new object[] { prefix, method }; |
| 549 | + } |
| 550 | + } |
| 551 | + } |
| 552 | + |
| 553 | + [Theory] |
| 554 | + [MemberData(nameof(GetCrLfAndMethodCombinations))] |
| 555 | + public void LeadingCrLfAreAllowed(string startOfRequestLine, string httpMethod) |
| 556 | + { |
| 557 | + var rawTarget = "http://localhost/path1?q=123&w=xyzw"; |
| 558 | + Http1Connection.Reset(); |
| 559 | + // RawTarget, Path, QueryString are null after reset |
| 560 | + Assert.Null(Http1Connection.RawTarget); |
| 561 | + Assert.Null(Http1Connection.Path); |
| 562 | + Assert.Null(Http1Connection.QueryString); |
| 563 | + |
| 564 | + var ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"{startOfRequestLine}{httpMethod} {rawTarget} HTTP/1.1\r\n")); |
| 565 | + var reader = new SequenceReader<byte>(ros); |
| 566 | + Assert.True(Parser.ParseRequestLine(ParsingHandler, ref reader)); |
| 567 | + } |
| 568 | + |
519 | 569 | public StartLineTests() |
520 | 570 | { |
521 | 571 | MemoryPool = PinnedBlockMemoryPoolFactory.Create(); |
|
0 commit comments