In my server side code I'm creating the following response object:
var response = HttpContext.Current.Response;
response.Clear();
response.AddHeader("Content-Type", content.Type);
response.AddHeader("Content-Length", content.Length.ToString());
response.AddHeader("Content-Disposition",
string.Format("attachment; filename={0}; size={1}", Server.UrlEncode(content.FileName), content.Length.ToString()));
response.Flush();
response.BinaryWrite(content.Image);
response.Flush();
Is it possible something in this response object is causing the 403 and if so what? If I just run a blank aspx page I don't get a 403 it is only when it goes through the above code that a 403 occurs.
The issue is unlikely to be a mime type issue (so probably not related to the content type being text/plain), though that's an issue in itself.
Chances are that permissions are not setup correctly, or that .NET is not registered on the server properly. Try running aspnet_regiis on the server again.
Related
I am calling the MVC controller which returns a FileResult back using XMLHttpRequest.
For some reason i don't get a prompt for download/save the file , i do get the file content as the response from the get request(Checked in network tab).
I don't have the url of the file only have contentbytes, so can't use window.location
Please help.
Do not use XMLHttpRequest to open file link, do
Javascript redirect
window.location = "http://www.yoururl.com";
open popup with that link
Before returning the file in your controller action, try to add a content-disposition header (directly as below, or using System.Net.Mime.ContentDisposition).
Response.AppendHeader("content-disposition", "inline; filename=" + fileName);
Also have a look at RFC 6266
On the client side, call the url that returns the attachment:
window.open('..../controller-name/action-that-returns-the-file');
Our web application (ASP.NET Web Forms) has a page that will display a recently generated PDF file to users. Because the PDF file is sometimes quite large, we've implemented a "streaming" approach to send it down to the client browser in chunks.
Despite sending the data down in chunks, we know the full size of the file prior to sending it, so we set the Content-Length header appropriately. This has been working in our production environment for awhile (and continues to work in our test environment with a virtually identical configuration) until today. The issue reported was that Chrome would attempt to open the PDF file but would hang with the "Loading" animation stuck.
Because everything was still working fine in our test environment I was able to use Firebug to take a look at the response headers that were coming back in both environments. In the test environment, I was seeing a proper 'Content-Length' header, while in production that had been replaced with a Transfer-Encoding: chunked header. Chrome doesn't like this, hence the hang-up.
I've read some articles and posts talking about how the Transfer-Encoding header can show up when no Content-Length header is provided, but we are specifying the Content-Length header and everything still appears to work while running the same code for the same PDF file on a test server.
Both test and production servers are running IIS 7.5 and both have Dynamic and Static Compression enabled.
Here is the code in question:
var fileInfo = new FileInfo(fileToSendDown);
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "filename=test.pdf");
Response.AddHeader("Content-Length", fileInfo.Length.ToString());
var buffer = new byte[1024];
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
int read;
while ((read = fs.Read(buffer, 0, 1024)) > 0)
{
if (!response.IsClientConnected) break;
Response.OutputStream.Write(buffer, 0, read);
Response.Flush();
}
}
I was fortunate to see the same behavior on my local workstation so using the debugger I have been able to see that the 'Transfer-Encoding: chunked' header is being set on the 2nd pass through the while loop during the call to 'Flush'. At that point, the response has both a Content-Length header and Transfer-Encoding header, but somehow by the time the response reaches the browser Firebug is only showing the Transfer-Encoding header.
UPDATE
I think I've tracked this down to using a combination of sending the data down in "chunks" AND attaching a 'Filter' to the HttpResponse object (we were using a filter to track the size of viewstate being sent down to each page). There's no sense in us using an HTTP filter when sending a PDF down to the browser, so clearing the filter here has resolved our issue. I decided to dig in a little deeper purely out of curiosity and have updated this question should anyone else ever stumble onto this problem in the future.
I've got a simple app up on AppHarbor that reproduces the issue: http://transferencodingtest.apphb.com/. If you check both the 'Use Filter?' and 'Send In Chunks?' boxes you should be able to see the 'transfer-encoding: chunked' header show up (using Chrome dev tools, Firebug, Fiddler, whatever). If either of the boxes are not checked, you'll get a proper content-length header. The underlying code is up on github so you can see what's going on behind the scenes:
https://github.com/appakz/TransferEncodingTest
Note that to repro locally you'd need to setup a local website in IIS 7.5 (7 may also work, I haven't tried). The ASP .NET development server that ships with Visual Studio DOES NOT repro the issue.
I've added some more details to a blog post here: 'Content-Length' Header Replaced With 'Transfer-Encoding: Chunked' in ASP .NET
From an article on MSDN it seems that you can disable chunked encoding:
appcmd set config /section:asp /enableChunkedEncoding:False
But it's mentioned under ASP settings, so it may not apply to a response generated from an ASP.NET handler.
Once Response.Flush() has been called, the response body in in the process of being sent to the client, so no additional headers can be added to the response. I find it very unlikely that a second call to Response.Flush() is adding the Transfer-Encoding header at that time.
You say you have compression enabled. That almost always requires a chunked response. So it would make sense that if the server knows the Content-Length prior to compression, it might substitute that header for the Transfer-Encoding header and chunk the response. However, even with compression enabled on the server, the client has to explicitally state support for compression in its Accept-Encoding request header or else the server cannot compress the response. Did you check for that in your tests?
On a final note, since you are calling Response.Flush() manually, try setting Response.Buffer = True and Response.BufferOutput = False. Apparently they have conflicting effects on how Response.Flush() operates. See the comment at the bottom of this page and this page.
I had a similar problem when I was writing a large CSV (The file didn't exist I write a string line by line by iterating through an in memory collection and generating the line) by calling Response.Write on the Response stream with BufferOutput set to false, but the solution was to change
Reponse.ContentType = 'text/csv' to Reponse.ContentType = 'application/octet-stream'
When the content type wasn't set to application/octet-stream a bunch of other response headers were added such as Content-Encoding - gzip
In a web site I capture the http POST request with a HttpModule as in this answer.
After reading the body of the POST in the context's BeginRequest event I would like to return as quickly as possible an "OK" response to the client.
What would be the best way to prevent further processing in IIS (7.5 integrated mode)?
I believe this one is the fastest:
Response.Clear();
Response.ClearHeaders();
Response.StatusCode = 200;
Response.StatusDescription = "OK";
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
Call HttpResponse.End(). It will flush any pending content (your OK response) and then end the request.
Is there any site or some one can provide me a sample PROFIND request please.
I tried the PROFIND code sample from MSDN but getting 400 Bad request.
Unable to understand why this is happening.
Previously posted the question at Getting 400 Bad request from WebDav Server
Any suggestions will be greatly helpfull.
Edit
#Julian,
Have updated my request body to the following:
strBody = "<?xml version='1.0' encoding='utf-8'?>"
+ "<propfind xmlns='DAV:'>"
+ "<allprop/>"
+ "</propfind>";
as explained at RFC 4918, Section 9.1
But I am still getting the 400 Bad request Error. M I missing any Headers . Please suggest I am setting the following Header Information:
System.Net.HttpWebRequest Request;
Request.Credentials = MyCredentialCache;
Request.Method = "PROPFIND";
bytes = Encoding.UTF8.GetBytes((string)strBody);
Request.ContentType = "text/xml";
Do I need to set or specify something additional. The full code is in my Previosu Question.
Thanks,
Subhen
Ok I was missing the Depth Header and for that reason the webserver was returning Method Not allowed error.
MSDN clearlystates that
A PROPFIND with depth value of "infinity" is not supported in the public store that is accessible to MAPI clients such as Microsoft Outlook.
And the Bad request 404 error was generated because I was not using proxy. So What I did I commented the line which was not using any proxy and added the Depth Header.
// Request.Proxy = GlobalProxySelection.GetEmptyWebProxy();
Request.Headers.Add("Depth", "1");
I am running a website on IIS6 for ASP.NET application and enabled compression, which worked fine for the .aspx web pages.
What isn't working is downloaded binary files that are transmitted as part of a postback response: e.g. link button is 'download to excel' - user clicks and the code generates a binary file, does a Response.Clear() and then writes the file to the Response.OutputStream.
A response is seen by browsers but it is always zero bytes. I assume therefore that web browsers are expecting a compressed response, and as the raw binary isn't a valid compressed stream it fails. I'm puzzled as to why this should be if I've cleared the response - surely the response headers (specifying compression) are also cleared?
So two questions arise:
1) how do I compress the binary file to send a compressed response?
2) how can I check at runtime to see if IIS compression is enabled?
Cheers
I would disable compression and check whether this still works, just to isolate the fact that this is indeed due to IIS compression. I'm telling you that 'cos I'm running a IIS/Compression enabled site which provides PDF files (binary) without a problem.
Anyway here's the part of code which works for me.
Response.Clear();
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
Response.AddHeader("Content-Length", fileInfo.Length.ToString());
Response.AddHeader("Content-transfer-encoding", "8bit");
Response.AddHeader("Cache-Control", "private");
Response.AddHeader("Pragma", "cache");
Response.AddHeader("Expires", "0");
Response.ContentType = "application/pdf";
Response.WriteFile(filePath);
Response.Flush();
Response.Close();
HttpContext.Current.ApplicationInstance.CompleteRequest();