Reputation: 5458
Since a newer version of the Android WebView (currently running on v48), pdf downloads form my application stopped to work. Downloading from desktop browsers, WP10 and iOS also function properly.
The behavior:
It says, the download has started... then a few minutes later I get a notification " Download was unsuccessful".
The download comes from a WebApi controller, hosted on Azure. I tried tons of different suggested https headers and combination of headers. I also compared headers coming from other websites, where the download works on my device. No success.
I got curious and impemlented the download in an Asp.Net Mvc (5) controller (same project) and modified the headers that they were exactly like in the WebApi (2.2) counterpart. => download worked!. Compared both responses in Fiddler, except the Url - they look exactly the same.
Any idea what else could be the difference?
Here just some code bits:
MVC test (working)
public FileResult CoolDocument()
{
// Some hardcoded binary data (minimum valid pdf)
byte[] bytearr = new byte[] { 37, 80, ... };
// Making headers look the same as in the WebApi response
Response.AddHeader("Content-Disposition", "attachment; filename=\"test.pdf\"");
Response.Headers.Add("Expires", "-1");
Response.Headers.Add("Cache-Control", "no-cache");
Response.Headers.Add("X-Application-Version", "1.0.5919.31987");
Response.Headers.Add("X-Environment", "Acceptance");
Response.Headers.Add("Pragma", "no-cache");
return File(bytearr, "application/pdf");
}
WebApi test (not working) extra headers come form a filter, but I tried it without them too
[HttpGet]
public HttpResponseMessage CoolDocument()
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
/// Some hardcoded binary data (minimum valid pdf)
byte[] bytearr = new byte[] { 37, 80, ... };
response.Content = new ByteArrayContent(bytearr);
response.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/pdf");
response.Content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment") { FileName = "\"test.pdf\"", };
return response;
}
Here is how the headers look like in Fiddler:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 2729
Content-Type: application/pdf
Expires: -1
Server: Microsoft-IIS/8.0
X-Environment: Acceptance
X-Application-Version: 1.0.5919.31987
Content-Disposition: attachment; filename="test.pdf"
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 16 Mar 2016 16:50:41 GMT
Upvotes: 2
Views: 849
Reputation: 5458
Finally figured out what went wrong.
Android (and Windows Phone 8.1 too) makes two requests when starting a download.
I assume, that the first one is coming from the browser (Chrome) and the second one from the android download manager.
The second request had different request headers than the original request. I noticed this second request only after I started to debug the server code remotely, because the request from the download manager has logically not been recorded in the chrome developer tools.
Anyway, this second request caused my "languge-filter" to throw an exception, because of a dumb null pointer exception occurred by reading out the Accept-Language Header - which was not present in the second request.
Upvotes: 1