From 97bc50c60bc80c64663170b078345ec91cc3bce7 Mon Sep 17 00:00:00 2001 From: ManickaP Date: Thu, 17 Apr 2025 10:47:03 +0200 Subject: [PATCH] Remove quotes from Content-Disposition string properties, same way as ASP does it --- .../System/Net/Http/HttpClientHandlerTest.cs | 2 +- .../Headers/ContentDispositionHeaderValue.cs | 5 +- .../ContentDispositionHeaderValueTest.cs | 50 +++++++++---------- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 946381dee0b4b8..7187204512a844 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -646,7 +646,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => Assert.Contains("close", resp.Headers.Connection); Assert.True(resp.Headers.ConnectionClose.GetValueOrDefault()); Assert.Equal("attachment", resp.Content.Headers.ContentDisposition.DispositionType); - Assert.Equal("\"fname.ext\"", resp.Content.Headers.ContentDisposition.FileName); + Assert.Equal("fname.ext", resp.Content.Headers.ContentDisposition.FileName); Assert.Contains("gzip", resp.Content.Headers.ContentEncoding); Assert.Contains("da", resp.Content.Headers.ContentLanguage); Assert.Equal(new Uri("/index.htm", UriKind.Relative), resp.Content.Headers.ContentLocation); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentDispositionHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentDispositionHeaderValue.cs index 5a179198bc0235..d6f4f978d75dc5 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentDispositionHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentDispositionHeaderValue.cs @@ -188,8 +188,7 @@ object ICloneable.Clone() public static ContentDispositionHeaderValue Parse(string input) { int index = 0; - return (ContentDispositionHeaderValue)GenericHeaderParser.ContentDispositionParser.ParseValue(input, - null, ref index); + return (ContentDispositionHeaderValue)GenericHeaderParser.ContentDispositionParser.ParseValue(input, null, ref index); } public static bool TryParse([NotNullWhen(true)] string? input, [NotNullWhen(true)] out ContentDispositionHeaderValue? parsedValue) @@ -349,7 +348,7 @@ private void SetDate(string parameter, DateTimeOffset? date) return result; } // May not have been encoded. - return nameParameter.Value; + return IsQuoted(nameParameter.Value) ? nameParameter.Value!.Substring(1, nameParameter.Value.Length - 2) : nameParameter.Value; } return null; } diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/ContentDispositionHeaderValueTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/ContentDispositionHeaderValueTest.cs index 5601ad137d2719..ddb153163d515e 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Headers/ContentDispositionHeaderValueTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/ContentDispositionHeaderValueTest.cs @@ -153,7 +153,7 @@ public void FileName_UnknownOrBadEncoding_PropertyFails() Assert.Equal(1, contentDisposition.Parameters.Count); Assert.Equal("FILENAME", contentDisposition.Parameters.First().Name); Assert.Equal("\"=?utf-99?Q?R=mlsZcODTmFtZS5iYXQ=?=\"", contentDisposition.Parameters.First().Value); - Assert.Equal("\"=?utf-99?Q?R=mlsZcODTmFtZS5iYXQ=?=\"", contentDisposition.FileName); + Assert.Equal("=?utf-99?Q?R=mlsZcODTmFtZS5iYXQ=?=", contentDisposition.FileName); contentDisposition.FileName = "new_name"; Assert.Equal("new_name", contentDisposition.FileName); @@ -677,7 +677,7 @@ public void ContentDispositionHeader_Valid2_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid2"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "inline", @"""foo.html"""); + ValidateHeaderValues(header, "inline", @"foo.html"); } [Fact] @@ -685,7 +685,7 @@ public void ContentDispositionHeader_Valid3_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid3"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "inline", @"""Not an attachment!"""); + ValidateHeaderValues(header, "inline", @"Not an attachment!"); } [Fact] @@ -693,7 +693,7 @@ public void ContentDispositionHeader_Valid4_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid4"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "inline", @"""foo.pdf"""); + ValidateHeaderValues(header, "inline", @"foo.pdf"); } [Fact] @@ -717,7 +717,7 @@ public void ContentDispositionHeader_Valid7_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid7"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo.html"""); + ValidateHeaderValues(header, "attachment", @"foo.html"); } [Fact] @@ -725,7 +725,7 @@ public void ContentDispositionHeader_Valid8_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid8"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""f\oo.html"""); + ValidateHeaderValues(header, "attachment", @"f\oo.html"); } [Fact] @@ -733,7 +733,7 @@ public void ContentDispositionHeader_Valid9_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid9"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""\""quoting\"" tested.html"""); + ValidateHeaderValues(header, "attachment", @"\""quoting\"" tested.html"); } [Fact] @@ -741,7 +741,7 @@ public void ContentDispositionHeader_Valid10_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid10"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""Here's a semicolon;.html"""); + ValidateHeaderValues(header, "attachment", @"Here's a semicolon;.html"); } [Fact] @@ -749,7 +749,7 @@ public void ContentDispositionHeader_Valid11_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid11"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo.html"""); + ValidateHeaderValues(header, "attachment", @"foo.html"); ValidateExtensionParameter(header, "foo", @"""bar"""); } @@ -758,7 +758,7 @@ public void ContentDispositionHeader_Valid12_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid12"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo.html"""); + ValidateHeaderValues(header, "attachment", @"foo.html"); ValidateExtensionParameter(header, "foo", @"""\""\\"""); } @@ -767,7 +767,7 @@ public void ContentDispositionHeader_Valid13_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid13"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo.html"""); + ValidateHeaderValues(header, "attachment", @"foo.html"); } [Fact] @@ -791,7 +791,7 @@ public void ContentDispositionHeader_Valid16_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid16"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo-\u00E4.html"""); + ValidateHeaderValues(header, "attachment", @"foo-\u00E4.html"); } [Fact] @@ -799,7 +799,7 @@ public void ContentDispositionHeader_Valid17_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid17"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo-ä.html"""); + ValidateHeaderValues(header, "attachment", @"foo-ä.html"); } [Fact] @@ -807,7 +807,7 @@ public void ContentDispositionHeader_Valid18_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid18"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo-%41.html"""); + ValidateHeaderValues(header, "attachment", @"foo-%41.html"); } [Fact] @@ -815,7 +815,7 @@ public void ContentDispositionHeader_Valid19_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid19"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""50%.html"""); + ValidateHeaderValues(header, "attachment", @"50%.html"); } [Fact] @@ -823,7 +823,7 @@ public void ContentDispositionHeader_Valid20_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid20"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo-%\41.html"""); + ValidateHeaderValues(header, "attachment", @"foo-%\41.html"); } [Fact] @@ -840,7 +840,7 @@ public void ContentDispositionHeader_Valid22_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid22"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""\u00E4-%41.html"""); + ValidateHeaderValues(header, "attachment", @"\u00E4-%41.html"); } [Fact] @@ -848,7 +848,7 @@ public void ContentDispositionHeader_Valid23_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid23"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo-%c3%a4-%e2%82%ac.html"""); + ValidateHeaderValues(header, "attachment", @"foo-%c3%a4-%e2%82%ac.html"); } [Fact] @@ -856,7 +856,7 @@ public void ContentDispositionHeader_Valid24_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid24"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo.html"""); + ValidateHeaderValues(header, "attachment", @"foo.html"); } [Fact] @@ -873,7 +873,7 @@ public void ContentDispositionHeader_Valid26_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid26"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""/foo.html"""); + ValidateHeaderValues(header, "attachment", @"/foo.html"); } [Fact] @@ -881,7 +881,7 @@ public void ContentDispositionHeader_Valid27_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid27"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""\\foo.html"""); + ValidateHeaderValues(header, "attachment", @"\\foo.html"); } [Fact] @@ -1056,7 +1056,7 @@ public void ContentDispositionHeader_Valid46_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid46"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo-ae.html"""); + ValidateHeaderValues(header, "attachment", @"foo-ae.html"); ValidateExtensionParameter(header, "filename*", @"UTF-8''foo-%c3%a4.html"); } @@ -1065,7 +1065,7 @@ public void ContentDispositionHeader_Valid47_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid47"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo-ae.html"""); + ValidateHeaderValues(header, "attachment", @"foo-ae.html"); ValidateExtensionParameter(header, "filename*", @"UTF-8''foo-%c3%a4.html"); } @@ -1074,7 +1074,7 @@ public void ContentDispositionHeader_Valid48_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid48"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""foo.html"""); + ValidateHeaderValues(header, "attachment", @"foo.html"); ValidateExtensionParameter(header, "foobar", @"x"); } @@ -1083,7 +1083,7 @@ public void ContentDispositionHeader_Valid49_Success() { ContentDispositionValue cd = ContentDispositionTestCases["valid49"]; ContentDispositionHeaderValue header = TryParse(cd); - ValidateHeaderValues(header, "attachment", @"""=?ISO-8859-1?Q?foo-=E4.html?="""); + ValidateHeaderValues(header, "attachment", @"=?ISO-8859-1?Q?foo-=E4.html?="); } #endregion