views:

274

answers:

3

I'm downloading a file, from a webserver, using the code below, and am recieving this error:

The Error: Error saving file from URL:The server committed a protocol violation.

Section=ResponseHeader Detail='Content-Length' header value is invalid

From running Fiddler while this is running, it says:

Content-Length response header is not a valid unsigned integer Content-Length: 13312583

The Code:

public static bool SaveFileFromURL(string url, string destinationFileName, int timeoutInSeconds)
        {
            //SetAllowUnsafeHeaderParsing20();
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            SettingsSection section = (SettingsSection)config.GetSection("system.net/settings");
            section.HttpWebRequest.UseUnsafeHeaderParsing = false;
            config.Save();

            // Create a web request to the URL
            HttpWebRequest MyRequest = (HttpWebRequest)WebRequest.Create(url);
            MyRequest.UseDefaultCredentials = true;
            MyRequest.ContentLength = 0;

            MyRequest.Timeout = timeoutInSeconds * 1000;
            try
            {
                // Get the web response
                HttpWebResponse MyResponse = (HttpWebResponse)MyRequest.GetResponse();

                // Make sure the response is valid
                if (HttpStatusCode.OK == MyResponse.StatusCode)
                {
                    // Open the response stream
                    using (Stream MyResponseStream = MyResponse.GetResponseStream())
                    {
                        // Open the destination file
                        using (FileStream MyFileStream = new FileStream(destinationFileName, FileMode.OpenOrCreate, FileAccess.Write))
                        {
                            // Create a 4K buffer to chunk the file
                            byte[] MyBuffer = new byte[4096];
                            int BytesRead;
                            // Read the chunk of the web response into the buffer
                            while (0 < (BytesRead = MyResponseStream.Read(MyBuffer, 0, MyBuffer.Length)))
                            {
                                // Write the chunk from the buffer to the file
                                MyFileStream.Write(MyBuffer, 0, BytesRead);
                            }
                        }
                    }
                }
            }
            catch (Exception err)
            {
                throw new Exception("Error saving file from URL:" + err.Message, err);
            }
            return true;
        }

Update: If I pass the URL straight into a browser, the file is downloaded successfully, and the error is thrown on the GetResponse line.

Update 2: I get the same error with WebClient.Downloadfile:

public static bool DL_Webclient(string url, string destinationFileName)
{
    WebClient myWebClient = new WebClient();
    myWebClient.UseDefaultCredentials = true;
    myWebClient.DownloadFile(url, destinationFileName);

    return true;
}

Update 3: Having retrieved the other headers in the message (using Fiddler), they are:

HTTP/1.1 200 OK
Connection: close
Date: Wed, 03 Mar 2010 08:43:06 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Content-Length: 13314320
Content-Type: application/x-evsaveset
Set-Cookie: ASPSESSIONIDQQCQSCRC=CFHHJHADOIBCFAFOHFJCDNEG; path=/
Cache-control: private
A: 

Are there other HTTP headers present?

It might have to do with the 'Transfer-Encoding' header or similar rules. For more specific information about these headers and their effect on the Content-Length header can be found at the W3C website and More W3C website

Hope this helps,

Marvin Smit
I've added the other headers to the question (above)
Nick Haslam
Doesn't seem to be anything with the additional headers except for the Content-Type which i'm not familiar with "application/x-evsaveset". This is slowly starting to look like a bug in the HttpRequest class. I know these classes (.Net 2.0) do not work well together with REST services, but thats unrelated here AFAICS.Could you tell me what that Content-Type is. I would like to read up on that one. maybe theres a relation.
Marvin Smit
A: 

Could you not use WebClient.DownloadFile instead?

PaulB
Sadly, no, I've just tried that, and the same error message, see the code above. Thanks though...
Nick Haslam
+1  A: 

Can you get a tracelog of your application (http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html) and put it on pastebin? Then we can try to help.

The protocolviolationexception may be due to a number of things. One of them could be that the server is advertizing a content length of 100, and sending less (or more) data than that.

feroze