Our environment has multiple web servers running behind a load balancer. If I modify my host file to go directly to a web server which will by-pass the load balancer, the HttpWebRequest works fine. If I remove the entry in my host file and let the request go through the load balancer it returns 404. However, if I perform the same request using a simple .html file on the same computer I am running the HttpWebRequest from it all works fine whether there is a entry in my host file or not.
Any ideas why it would work through the browser(Chrome) with the html file, but not an HttpWebRequest?
The request is a POST request which uploads a file and 3 other parameters.
Thanks in advance for any ideas.
EDIT: I tried setting my UserAgent to Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1 which is what Chrome sends when I use the html file.
Here is the function I’m using and currently works when no load balancer is in the mix:
private void PostFileToWebServer(byte[] file)
{
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
var request = (HttpWebRequest)WebRequest.Create(_url);
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Method = "POST";
request.KeepAlive = true;
//Time in milliseconds
request.Timeout = 1200000;
request.Host = "ourdomain.com";
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1";
request.CookieContainer = new CookieContainer(100000);
var memStream = new MemoryStream();
byte[] boundarybytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
string formDataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
foreach(var key in _parameters.AllKeys)
{
string formData = string.Format(formDataTemplate, key, _parameters[key]);
byte[] formDataBytes = Encoding.UTF8.GetBytes(formData);
memStream.Write(formDataBytes, 0, formDataBytes.Length);
memStream.Write(boundarybytes, 0, boundarybytes.Length);
}
string header = string.Format("Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\r\n Content-Type: application/octet-stream\r\n\r\n", _fileName);
byte[] headerBytes = Encoding.UTF8.GetBytes(header);
memStream.Write(headerBytes, 0, headerBytes.Length);
memStream.Write(file, 0, file.Length);
memStream.Write(boundarybytes, 0, boundarybytes.Length);
request.ContentLength = memStream.Length;
Stream requestStream = request.GetRequestStream();
memStream.Position = 0;
var tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
var response = request.GetResponse();
Stream stream2 = response.GetResponseStream();
var reader2 = new StreamReader(stream2);
System.Diagnostics.Debug.WriteLine(reader2.ReadToEnd());
response.Close();
}
EDIT: I commented out request.ContentType = "multipart/form-data; boundary=" + boundary; and it works with the load balancer. Anyone have an explanation for this?
Ok, me and Fiddler had a long conversation on the differences between the successful call and the unsuccessful call. Fiddler says the last boundary of the successful called sent from the browser has an extra “–” at the end of it. When I put that, all is well with the world and I can keep my Content-Type set as it is.