|
2 | 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
3 | 3 |
|
4 | 4 | using System;
|
| 5 | +using System.Collections.Generic; |
5 | 6 | using System.Text;
|
6 | 7 | using System.Threading;
|
7 | 8 | using System.Threading.Tasks;
|
@@ -692,6 +693,140 @@ public void EntryIsFresh_IgnoresRequestVerificationWhenSpecified()
|
692 | 693 | Assert.True(context.EntryIsFresh(httpContext.Response.GetTypedHeaders(), TimeSpan.FromSeconds(3), verifyAgainstRequest: false));
|
693 | 694 | }
|
694 | 695 |
|
| 696 | + [Fact] |
| 697 | + public void ConditionalRequestSatisfied_NotConditionalRequest_Fails() |
| 698 | + { |
| 699 | + var context = CreateTestContext(new DefaultHttpContext()); |
| 700 | + var cachedHeaders = new ResponseHeaders(new HeaderDictionary()); |
| 701 | + |
| 702 | + Assert.False(context.ConditionalRequestSatisfied(cachedHeaders)); |
| 703 | + } |
| 704 | + |
| 705 | + [Fact] |
| 706 | + public void ConditionalRequestSatisfied_IfUnmodifiedSince_FallsbackToDateHeader() |
| 707 | + { |
| 708 | + var utcNow = DateTimeOffset.UtcNow; |
| 709 | + var cachedHeaders = new ResponseHeaders(new HeaderDictionary()); |
| 710 | + var httpContext = new DefaultHttpContext(); |
| 711 | + var context = CreateTestContext(httpContext); |
| 712 | + |
| 713 | + httpContext.Request.GetTypedHeaders().IfUnmodifiedSince = utcNow; |
| 714 | + |
| 715 | + // Verify modifications in the past succeeds |
| 716 | + cachedHeaders.Date = utcNow - TimeSpan.FromSeconds(10); |
| 717 | + Assert.True(context.ConditionalRequestSatisfied(cachedHeaders)); |
| 718 | + |
| 719 | + // Verify modifications at present succeeds |
| 720 | + cachedHeaders.Date = utcNow; |
| 721 | + Assert.True(context.ConditionalRequestSatisfied(cachedHeaders)); |
| 722 | + |
| 723 | + // Verify modifications in the future fails |
| 724 | + cachedHeaders.Date = utcNow + TimeSpan.FromSeconds(10); |
| 725 | + Assert.False(context.ConditionalRequestSatisfied(cachedHeaders)); |
| 726 | + } |
| 727 | + |
| 728 | + [Fact] |
| 729 | + public void ConditionalRequestSatisfied_IfUnmodifiedSince_LastModifiedOverridesDateHeader() |
| 730 | + { |
| 731 | + var utcNow = DateTimeOffset.UtcNow; |
| 732 | + var cachedHeaders = new ResponseHeaders(new HeaderDictionary()); |
| 733 | + var httpContext = new DefaultHttpContext(); |
| 734 | + var context = CreateTestContext(httpContext); |
| 735 | + |
| 736 | + httpContext.Request.GetTypedHeaders().IfUnmodifiedSince = utcNow; |
| 737 | + |
| 738 | + // Verify modifications in the past succeeds |
| 739 | + cachedHeaders.Date = utcNow + TimeSpan.FromSeconds(10); |
| 740 | + cachedHeaders.LastModified = utcNow - TimeSpan.FromSeconds(10); |
| 741 | + Assert.True(context.ConditionalRequestSatisfied(cachedHeaders)); |
| 742 | + |
| 743 | + // Verify modifications at present |
| 744 | + cachedHeaders.Date = utcNow + TimeSpan.FromSeconds(10); |
| 745 | + cachedHeaders.LastModified = utcNow; |
| 746 | + Assert.True(context.ConditionalRequestSatisfied(cachedHeaders)); |
| 747 | + |
| 748 | + // Verify modifications in the future fails |
| 749 | + cachedHeaders.Date = utcNow - TimeSpan.FromSeconds(10); |
| 750 | + cachedHeaders.LastModified = utcNow + TimeSpan.FromSeconds(10); |
| 751 | + Assert.False(context.ConditionalRequestSatisfied(cachedHeaders)); |
| 752 | + } |
| 753 | + |
| 754 | + [Fact] |
| 755 | + public void ConditionalRequestSatisfied_IfNoneMatch_Overrides_IfUnmodifiedSince_ToPass() |
| 756 | + { |
| 757 | + var utcNow = DateTimeOffset.UtcNow; |
| 758 | + var cachedHeaders = new ResponseHeaders(new HeaderDictionary()); |
| 759 | + var httpContext = new DefaultHttpContext(); |
| 760 | + var requestHeaders = httpContext.Request.GetTypedHeaders(); |
| 761 | + var context = CreateTestContext(httpContext); |
| 762 | + |
| 763 | + // This would fail the IfUnmodifiedSince checks |
| 764 | + requestHeaders.IfUnmodifiedSince = utcNow; |
| 765 | + cachedHeaders.LastModified = utcNow + TimeSpan.FromSeconds(10); |
| 766 | + |
| 767 | + requestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { EntityTagHeaderValue.Any }); |
| 768 | + Assert.True(context.ConditionalRequestSatisfied(cachedHeaders)); |
| 769 | + } |
| 770 | + |
| 771 | + [Fact] |
| 772 | + public void ConditionalRequestSatisfied_IfNoneMatch_Overrides_IfUnmodifiedSince_ToFail() |
| 773 | + { |
| 774 | + var utcNow = DateTimeOffset.UtcNow; |
| 775 | + var cachedHeaders = new ResponseHeaders(new HeaderDictionary()); |
| 776 | + var httpContext = new DefaultHttpContext(); |
| 777 | + var requestHeaders = httpContext.Request.GetTypedHeaders(); |
| 778 | + var context = CreateTestContext(httpContext); |
| 779 | + |
| 780 | + // This would pass the IfUnmodifiedSince checks |
| 781 | + requestHeaders.IfUnmodifiedSince = utcNow; |
| 782 | + cachedHeaders.LastModified = utcNow - TimeSpan.FromSeconds(10); |
| 783 | + |
| 784 | + requestHeaders.IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") }); |
| 785 | + Assert.False(context.ConditionalRequestSatisfied(cachedHeaders)); |
| 786 | + } |
| 787 | + |
| 788 | + [Fact] |
| 789 | + public void ConditionalRequestSatisfied_IfNoneMatch_AnyWithoutETagInResponse_Passes() |
| 790 | + { |
| 791 | + var cachedHeaders = new ResponseHeaders(new HeaderDictionary()); |
| 792 | + var httpContext = new DefaultHttpContext(); |
| 793 | + var context = CreateTestContext(httpContext); |
| 794 | + |
| 795 | + httpContext.Request.GetTypedHeaders().IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") }); |
| 796 | + |
| 797 | + Assert.False(context.ConditionalRequestSatisfied(cachedHeaders)); |
| 798 | + } |
| 799 | + |
| 800 | + [Fact] |
| 801 | + public void ConditionalRequestSatisfied_IfNoneMatch_ExplicitWithMatch_Passes() |
| 802 | + { |
| 803 | + var cachedHeaders = new ResponseHeaders(new HeaderDictionary()) |
| 804 | + { |
| 805 | + ETag = new EntityTagHeaderValue("\"E1\"") |
| 806 | + }; |
| 807 | + var httpContext = new DefaultHttpContext(); |
| 808 | + var context = CreateTestContext(httpContext); |
| 809 | + |
| 810 | + httpContext.Request.GetTypedHeaders().IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") }); |
| 811 | + |
| 812 | + Assert.True(context.ConditionalRequestSatisfied(cachedHeaders)); |
| 813 | + } |
| 814 | + |
| 815 | + [Fact] |
| 816 | + public void ConditionalRequestSatisfied_IfNoneMatch_ExplicitWithoutMatch_Fails() |
| 817 | + { |
| 818 | + var cachedHeaders = new ResponseHeaders(new HeaderDictionary()) |
| 819 | + { |
| 820 | + ETag = new EntityTagHeaderValue("\"E2\"") |
| 821 | + }; |
| 822 | + var httpContext = new DefaultHttpContext(); |
| 823 | + var context = CreateTestContext(httpContext); |
| 824 | + |
| 825 | + httpContext.Request.GetTypedHeaders().IfNoneMatch = new List<EntityTagHeaderValue>(new[] { new EntityTagHeaderValue("\"E1\"") }); |
| 826 | + |
| 827 | + Assert.False(context.ConditionalRequestSatisfied(cachedHeaders)); |
| 828 | + } |
| 829 | + |
695 | 830 | private static ResponseCachingContext CreateTestContext(HttpContext httpContext)
|
696 | 831 | {
|
697 | 832 | return CreateTestContext(
|
|
0 commit comments