dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.27k stars 4.73k forks source link

response.Content.Headers.ContentDisposition.FileName contains quotes #32765

Open dozed opened 4 years ago

dozed commented 4 years ago

Describe the bug

When creating a Content-Disposition header:

var contentDispositionHeader = new ContentDisposition()
{
    FileName = "foo bar.pdf",
    DispositionType = "attachment"
};
ctx.Response.Headers.Add("Content-Disposition", contentDispositionHeader.ToString());

response.Content.Headers.ContentDisposition.FileName contains quotes:

var fileName = response.Content.Headers.ContentDisposition.FileName;
Assert.Equal("foo bar.pdf", fileName);

Evaluates to:

Assert.Equal() Failure
          ↓ (pos 0)
Expected: foo bar.pdf
Actual:   "foo bar.pdf"
          ↑ (pos 0)

I would expect that the quotes would be removed.

To Reproduce

Further technical details

.NET Core SDK (reflecting any global.json):
 Version:   3.1.101
 Commit:    b377529961

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.17763
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.1.101\

Host (useful for support):
  Version: 3.1.1
  Commit:  a1388f194c

.NET Core SDKs installed:
  2.2.100 [C:\Program Files\dotnet\sdk]
  3.0.100 [C:\Program Files\dotnet\sdk]
  3.1.101 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Tratcher commented 4 years ago

To clarify, there are three types for Content-Disposition:

            var contentDispositionHeader = new System.Net.Mime.ContentDisposition()
            {
                FileName = "foo bar.pdf",
                DispositionType = "attachment"
            };
            string result = contentDispositionHeader.ToString();

            var parsed = Microsoft.Net.Http.Headers.ContentDispositionHeaderValue.Parse(result);
            Assert.Equal("foo bar.pdf", parsed.FileName);  // Pass

            var parsed0 = System.Net.Http.Headers.ContentDispositionHeaderValue.Parse(result);
            Assert.Equal("foo bar.pdf", parsed0.FileName); // Fails

Your issue is with the one in System.Net.Http.Headers, which is used by HttpClient. I'm going to transfer this issue to runtime where HttpClient lives.

karelz commented 4 years ago

Same behavior of System.Net.Http.Headers.ContentDispositionHeaderValue.Parse on .NET Framework - also returns quoted text.

bender-ristone commented 3 years ago

the current specification says that it should always with quotes

https://tools.ietf.org/html/rfc2616#section-2.2

19.5.1 Content-Disposition -> Content-Disposition: attachment; filename="fname.ext"

karelz commented 3 years ago

I think the goal here is to remove the quotes from the property, not from the header which goes over the wire ...

foka commented 3 years ago

(Until this issue is fixed) If your server returns filename* you can rely on the FileNameStar property, instead of the bugged FileName.

Example (dotnet Version: 5.0.101, Commit: d05174dc5a):

var response = await httpClient.GetAsync($"files/{id}");
// Response has a header:
// Content-Disposition: attachment; filename="foo bar.pdf"; filename*=UTF-8''foo%20bar.pdf
Console.WriteLine(response.Content.Headers.ContentDisposition.FileName); // "foo bar.pdf"
Console.WriteLine(response.Content.Headers.ContentDisposition.FileNameStar); // foo bar.pdf
flibustier7seas commented 11 months ago

When is the bug going to be fixed?

karelz commented 11 months ago

@flibustier7seas no plans yet, there are bugs and features which need our attention more and we didn't get to the medium-upvoted issues yet. That said, we would be happy to take a contribution if anyone is interested.