Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Returning a file, accept-ranges headers, and browser behaviors #6780

Closed
nickalbrecht opened this issue Sep 7, 2017 · 2 comments
Closed

Returning a file, accept-ranges headers, and browser behaviors #6780

nickalbrecht opened this issue Sep 7, 2017 · 2 comments

Comments

@nickalbrecht
Copy link

nickalbrecht commented Sep 7, 2017

In ASPNET Core 2, any time you return a file from actual binary data (Either byte[] or Stream from my testing, haven't tried others yet), it automatically opts you into it sending headers to the browser of accept-ranges, and content-length. But the problem is that if the browser tries to take advantage of this, and your action may end up getting pinged multiple times, even though you likely have provided the entire file on the first request/response cycle. This results in repeat requests that you may not expect, or have planned for. In some cases can prevent the file from loading correctly on consumption because you're returning the same bytes no matter what range was asked for, simply by upgrading to ASPNET Core 2. There is no documentation about how to support this from what I can tell, and no details warning people about the change.

Ideally, the developer should be able to opt out of this behavior, or be required to explicitly opt in.

There should be some sort of documentation on how to support range requests.

Steps to reproduce
Create a new ASPNET Core 2 MVC app
Add a new action on the Home controller with the following

public IActionResult FileExample([FromServices]IHostingEnvironment hostingEnvironment)
{
    //Using https://www.iso.org/files/live/sites/isoorg/files/archive/pdf/en/annual_report_2009.pdf copied to the project folder as my example PDF
    //I just googled for a random PDF, my real world example pulls its files from a SQL DB
    var buffer = System.IO.File.ReadAllBytes(Path.Combine(hostingEnvironment.ContentRootPath, "annual_report_2009.pdf")); 
    var contentDisposition = new System.Net.Mime.ContentDisposition() { FileName = "annual_report_2009.pdf.pdf", Inline = true };
    Response.Headers.Add("Content-Disposition", contentDisposition.ToString());
    return File(buffer, "application/pdf");
}

In this example, I saw Chrome request this action 5 times for one request in the browser, and IE requests it 8.

@Eilon Eilon added this to the 2.1.0 milestone Sep 7, 2017
@Eilon
Copy link
Member

Eilon commented Sep 7, 2017

@jbagga - can you add our fix proposal to this bug?

@jbagga
Copy link
Contributor

jbagga commented Sep 26, 2017

The fix will introduce public API overloads(File(...)) that allow the user to specify if they want to enable range processing (off by default) for any of the four different FileResult types.

If enabled (set enableRangeProcessing to true), the Accept-Ranges header will be added to the response headers and if range headers are present in the request, the range will be processed accordingly.

However, no range related headers will be added by default.

This should avoid multiple requests because of the presence of Accept-Ranges in the response. See https://stackoverflow.com/questions/1817750/do-most-browsers-make-multiple-http-requests-when-displaying-a-pdf-from-within-t

cc @Tratcher

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants