|
4 | 4 | using System;
|
5 | 5 | using System.IO;
|
6 | 6 | using System.Text;
|
| 7 | +using System.Threading; |
7 | 8 | using Microsoft.AspNetCore.Http.Features;
|
8 | 9 | using Microsoft.AspNetCore.Server.Kestrel;
|
9 | 10 | using Microsoft.AspNetCore.Server.Kestrel.Internal;
|
@@ -520,5 +521,182 @@ public void InitializeStreamsResetsStreams()
|
520 | 521 | Assert.Same(originalResponseBody, frame.ResponseBody);
|
521 | 522 | Assert.Same(originalDuplexStream, frame.DuplexStream);
|
522 | 523 | }
|
| 524 | + |
| 525 | + [Fact] |
| 526 | + public void FlushSetsTransferEncodingSetForUnknownLengthBodyResponse() |
| 527 | + { |
| 528 | + // Arrange |
| 529 | + var connectionContext = new ConnectionContext() |
| 530 | + { |
| 531 | + DateHeaderValueManager = new DateHeaderValueManager(), |
| 532 | + ServerAddress = ServerAddress.FromUrl("http://localhost:5000"), |
| 533 | + ServerOptions = new KestrelServerOptions(), |
| 534 | + SocketOutput = new MockSocketOuptut() |
| 535 | + }; |
| 536 | + var frame = new TestFrameProtectedMembers<object>(application: null, context: connectionContext); |
| 537 | + frame.InitializeHeaders(); |
| 538 | + frame.KeepAlive = true; |
| 539 | + frame.HttpVersion = KnownStrings.Http11Version; |
| 540 | + |
| 541 | + // Act |
| 542 | + frame.Flush(); |
| 543 | + |
| 544 | + // Assert |
| 545 | + Assert.True(frame.HasResponseStarted); |
| 546 | + Assert.True(frame.ResponseHeaders.ContainsKey("Transfer-Encoding")); |
| 547 | + } |
| 548 | + |
| 549 | + [Fact] |
| 550 | + public void FlushDoesNotSetTransferEncodingSetForNoBodyResponse() |
| 551 | + { |
| 552 | + // Arrange |
| 553 | + var connectionContext = new ConnectionContext() |
| 554 | + { |
| 555 | + DateHeaderValueManager = new DateHeaderValueManager(), |
| 556 | + ServerAddress = ServerAddress.FromUrl("http://localhost:5000"), |
| 557 | + ServerOptions = new KestrelServerOptions(), |
| 558 | + SocketOutput = new MockSocketOuptut() |
| 559 | + }; |
| 560 | + var frame = new TestFrameProtectedMembers<object>(application: null, context: connectionContext); |
| 561 | + frame.InitializeHeaders(); |
| 562 | + frame.KeepAlive = true; |
| 563 | + frame.HttpVersion = KnownStrings.Http11Version; |
| 564 | + ((IHttpResponseFeature)frame).StatusCode = 304; |
| 565 | + |
| 566 | + // Act |
| 567 | + frame.Flush(); |
| 568 | + |
| 569 | + // Assert |
| 570 | + Assert.True(frame.HasResponseStarted); |
| 571 | + Assert.False(frame.ResponseHeaders.ContainsKey("Transfer-Encoding")); |
| 572 | + } |
| 573 | + |
| 574 | + [Fact] |
| 575 | + public void FlushDoesNotSetTransferEncodingSetForHeadResponse() |
| 576 | + { |
| 577 | + // Arrange |
| 578 | + var connectionContext = new ConnectionContext() |
| 579 | + { |
| 580 | + DateHeaderValueManager = new DateHeaderValueManager(), |
| 581 | + ServerAddress = ServerAddress.FromUrl("http://localhost:5000"), |
| 582 | + ServerOptions = new KestrelServerOptions(), |
| 583 | + SocketOutput = new MockSocketOuptut() |
| 584 | + }; |
| 585 | + var frame = new TestFrameProtectedMembers<object>(application: null, context: connectionContext); |
| 586 | + frame.InitializeHeaders(); |
| 587 | + frame.KeepAlive = true; |
| 588 | + frame.HttpVersion = KnownStrings.Http11Version; |
| 589 | + frame.Method = KnownStrings.HttpHeadMethod; |
| 590 | + |
| 591 | + // Act |
| 592 | + frame.Flush(); |
| 593 | + |
| 594 | + // Assert |
| 595 | + Assert.True(frame.HasResponseStarted); |
| 596 | + Assert.False(frame.ResponseHeaders.ContainsKey("Transfer-Encoding")); |
| 597 | + } |
| 598 | + |
| 599 | + [Fact] |
| 600 | + public void WriteThrowsForNoBodyResponse() |
| 601 | + { |
| 602 | + // Arrange |
| 603 | + var connectionContext = new ConnectionContext() |
| 604 | + { |
| 605 | + DateHeaderValueManager = new DateHeaderValueManager(), |
| 606 | + ServerAddress = ServerAddress.FromUrl("http://localhost:5000"), |
| 607 | + ServerOptions = new KestrelServerOptions(), |
| 608 | + SocketOutput = new MockSocketOuptut() |
| 609 | + }; |
| 610 | + var frame = new TestFrameProtectedMembers<object>(application: null, context: connectionContext); |
| 611 | + frame.InitializeHeaders(); |
| 612 | + frame.KeepAlive = true; |
| 613 | + frame.HttpVersion = KnownStrings.Http11Version; |
| 614 | + ((IHttpResponseFeature)frame).StatusCode = 304; |
| 615 | + |
| 616 | + // Assert |
| 617 | + frame.Flush(); // Does not throw |
| 618 | + |
| 619 | + Assert.Throws<BadHttpResponseException>(() => frame.Write(new ArraySegment<byte>(new byte[1]))); |
| 620 | + Assert.ThrowsAsync<BadHttpResponseException>(() => frame.WriteAsync(new ArraySegment<byte>(new byte[1]), default(CancellationToken))); |
| 621 | + |
| 622 | + frame.Flush(); // Does not throw |
| 623 | + } |
| 624 | + |
| 625 | + [Fact] |
| 626 | + public void WriteDoesNotThrowForHeadResponse() |
| 627 | + { |
| 628 | + // Arrange |
| 629 | + var connectionContext = new ConnectionContext() |
| 630 | + { |
| 631 | + DateHeaderValueManager = new DateHeaderValueManager(), |
| 632 | + ServerAddress = ServerAddress.FromUrl("http://localhost:5000"), |
| 633 | + ServerOptions = new KestrelServerOptions(), |
| 634 | + SocketOutput = new MockSocketOuptut(), |
| 635 | + Log = new TestKestrelTrace() |
| 636 | + }; |
| 637 | + var frame = new TestFrameProtectedMembers<object>(application: null, context: connectionContext); |
| 638 | + frame.InitializeHeaders(); |
| 639 | + frame.KeepAlive = true; |
| 640 | + frame.HttpVersion = KnownStrings.Http11Version; |
| 641 | + frame.Method = KnownStrings.HttpHeadMethod; |
| 642 | + |
| 643 | + // Assert |
| 644 | + frame.Flush(); // Does not throw |
| 645 | + |
| 646 | + frame.Write(new ArraySegment<byte>(new byte[1])); |
| 647 | + |
| 648 | + frame.Flush(); // Does not throw |
| 649 | + } |
| 650 | + |
| 651 | + |
| 652 | + [Fact] |
| 653 | + public void ManuallySettingTransferEncodingThrowsForHeadResponse() |
| 654 | + { |
| 655 | + // Arrange |
| 656 | + var connectionContext = new ConnectionContext() |
| 657 | + { |
| 658 | + DateHeaderValueManager = new DateHeaderValueManager(), |
| 659 | + ServerAddress = ServerAddress.FromUrl("http://localhost:5000"), |
| 660 | + ServerOptions = new KestrelServerOptions(), |
| 661 | + SocketOutput = new MockSocketOuptut(), |
| 662 | + Log = new TestKestrelTrace() |
| 663 | + }; |
| 664 | + var frame = new TestFrameProtectedMembers<object>(application: null, context: connectionContext); |
| 665 | + frame.InitializeHeaders(); |
| 666 | + frame.KeepAlive = true; |
| 667 | + frame.HttpVersion = KnownStrings.Http11Version; |
| 668 | + frame.Method = KnownStrings.HttpHeadMethod; |
| 669 | + |
| 670 | + //Act |
| 671 | + frame.ResponseHeaders.Add("Transfer-Encoding", "chunked"); |
| 672 | + |
| 673 | + // Assert |
| 674 | + Assert.Throws<BadHttpResponseException>(() => frame.Flush()); |
| 675 | + } |
| 676 | + |
| 677 | + [Fact] |
| 678 | + public void ManuallySettingTransferEncodingThrowsForNoBodyResponse() |
| 679 | + { |
| 680 | + // Arrange |
| 681 | + var connectionContext = new ConnectionContext() |
| 682 | + { |
| 683 | + DateHeaderValueManager = new DateHeaderValueManager(), |
| 684 | + ServerAddress = ServerAddress.FromUrl("http://localhost:5000"), |
| 685 | + ServerOptions = new KestrelServerOptions(), |
| 686 | + SocketOutput = new MockSocketOuptut(), |
| 687 | + Log = new TestKestrelTrace() |
| 688 | + }; |
| 689 | + var frame = new TestFrameProtectedMembers<object>(application: null, context: connectionContext); |
| 690 | + frame.InitializeHeaders(); |
| 691 | + frame.KeepAlive = true; |
| 692 | + frame.HttpVersion = KnownStrings.Http11Version; |
| 693 | + ((IHttpResponseFeature)frame).StatusCode = 304; |
| 694 | + |
| 695 | + //Act |
| 696 | + frame.ResponseHeaders.Add("Transfer-Encoding", "chunked"); |
| 697 | + |
| 698 | + // Assert |
| 699 | + Assert.Throws<BadHttpResponseException>(() => frame.Flush()); |
| 700 | + } |
523 | 701 | }
|
524 | 702 | }
|
0 commit comments