KeepAliveException when using HttpWebRequest.GetResponse - c#

I am trying to POST an attachment to CouchDB using the HttpWebRequest. However, when I attempt "response = (HttpWebResponse)httpWebRequest.GetResponse();" I receive a WebException with the message "The underlying connection was closed: A connection that was expected to be kept alive was closed by the server."
I have found some articles stating that setting the keepalive to false and httpversion to 1.0 resolves the situation. I am finding that it does not yeilding the exact same error, plus I do not want to take that approach as I do not want to use the 1.0 version due to how it handles the connection.
Any suggestions or ideas are welcome. I'll try them all until one works!
public ServerResponse PostAttachment(Server server, Database db, Attachment attachment)
{
Stream dataStream;
HttpWebResponse response = null;
StreamReader sr = null;
byte[] buffer;
string json;
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
string headerTemplate = "Content-Disposition: form-data; name=\"_attachments\"; filename=\"" + attachment.Filename + "\"\r\n Content-Type: application/octet-stream\r\n\r\n";
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(headerTemplate);
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("http://" + server.Host + ":" +
server.Port.ToString() + "/" + db.Name + "/" + attachment.Document.Id);
httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundary;
httpWebRequest.Method = "POST";
httpWebRequest.KeepAlive = true;
httpWebRequest.ContentLength = attachment.Stream.Length + headerbytes.Length + boundarybytes.Length;
if (!string.IsNullOrEmpty(server.EncodedCredentials))
httpWebRequest.Headers.Add("Authorization", server.EncodedCredentials);
if (!attachment.Stream.CanRead)
throw new System.NotSupportedException("The stream cannot be read.");
// Get the request stream
try
{
dataStream = httpWebRequest.GetRequestStream();
}
catch (Exception e)
{
throw new WebException("Failed to get the request stream.", e);
}
buffer = new byte[server.BufferSize];
int bytesRead;
dataStream.Write(headerbytes,0,headerbytes.Length);
attachment.Stream.Position = 0;
while ((bytesRead = attachment.Stream.Read(buffer, 0, buffer.Length)) > 0)
{
dataStream.Write(buffer, 0, bytesRead);
}
dataStream.Write(boundarybytes, 0, boundarybytes.Length);
dataStream.Close();
// send the request and get the response
try
{
response = (HttpWebResponse)httpWebRequest.GetResponse();
}
catch (Exception e)
{
throw new WebException("Invalid response received from server.", e);
}
// get the server's response json
try
{
dataStream = response.GetResponseStream();
sr = new StreamReader(dataStream);
json = sr.ReadToEnd();
}
catch (Exception e)
{
throw new WebException("Failed to access the response stream.", e);
}
// close up all our streams and response
sr.Close();
dataStream.Close();
response.Close();
// Deserialize the server response
return ConvertTo.JsonToServerResponse(json);
}

After a considerable amount of research on the topic, I have decided to use PUT. While Futon uses the POST method, it is undocumented. For anyone reading this in the future, use the PUT method, it will make your life much easier.

Related

Http post request to send form data in image format

Hi I have below code to send the data, but in return I get server error with error code 500, the file is
not getting sent through the request
Can anyone tell me what I am doing wrong
FileStream rdr = new FileStream("C:/Users/AR485UY/Desktop/Test1.pdf", FileMode.Open)
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("url" );
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
req.Method = "POST";
req.ContentLength = rdr.Length;
req.ContentType = "multipart/form-data; boundary=" +boundary;
req.AllowWriteStreamBuffering = true;
Stream reqStream = req.GetRequestStream();
byte[] inData = new byte[rdr.Length];
int len = Convert.ToInt32(rdr.Length);
int bytesRead = rdr.Read(inData, 0, len);
reqStream.Write(inData, 0, len);
rdr.Close();
req.GetResponse();
reqStream.Close();
HTTP 500 Internal Server Error server error response code indicates that the server encountered an unexpected condition that prevented it from fulfilling the request.
if it never work :
Most likely have to validate your server side api,script,logs,events,diagnostics trace,file size limits.
Also try another approach in c#:
try
{
using(WebClient client = new WebClient())
{
string myFile = #"C:/Users/AR485UY/Desktop/Test1.pdf";
client.Credentials = CredentialCache.DefaultCredentials;
client.UploadFile(url, "POST", myFile);
}
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}

Internal Server error 500 : No file specified in the request body

I am using and API that accepts an image file and returns a JSON string as a response on console C# application. I am sending the image to the API using HTTP POST method and I keep getting an error message from the server saying: The remote server returned an error: (500) Internal Server Error. No specified file in the request body, the code I wrote so far:
public static void HttpUploadFile(string url, string file, string paramName, string contentType)
{
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
wr.ContentType = "multipart/form-data; boundary=" + boundary;
wr.Method = "POST";
wr.KeepAlive = true;
wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
Stream rs = wr.GetRequestStream();
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
string header = string.Format(headerTemplate, paramName, file, contentType);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
rs.Write(headerbytes, 0, headerbytes.Length-1);
FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
rs.Write(buffer, 0, bytesRead);
}
fileStream.Close();
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
rs.Write(trailer, 0, trailer.Length);
rs.Close();
WebResponse wresp = null;
try
{
wresp = wr.GetResponse();
Stream stream2 = wresp.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
Console.WriteLine(string.Format("File uploaded, server response is: {0}", reader2.ReadToEnd()));
Console.ReadKey();
}
catch (WebException ex)
{
Console.WriteLine("Error uploading file "+ ex);
WebResponse errResp = ex.Response;
Console.ReadKey();
using (Stream respStream = errResp.GetResponseStream())
{
StreamReader reader = new StreamReader(respStream);
string text = reader.ReadToEnd();
Console.WriteLine(text);
Console.ReadKey();
}
if (wresp != null)
{
wresp.Close();
wresp = null;
}
}
finally
{
wr = null;
}
}
I am sending to this method the following parameters from the main:
HttpUploadFile(URL,
#"SomeImage.jpg", "file", "image/jpg");
The Image location is in the solution's directory: Project/bin/debug.
The exact error message :
Error uploading file System.Net.WebException: The remote server returned an error: (500) Internal Server Error.
at System.Net.HttpWebRequest.GetResponse()
{"code": 500,"error": "Invalid Request - No file specified in the request body"}
I looked all over the internet for similar issues but couldn't find a solution for the problem, does anyone know what might be the error? or have any assumptions?

no http-connection possible after occurrence of server error 503

I build a windows-mobile 6.5 application (based on cf 2.0) and have a problem with a special test case of one method. So I hope someone can give me an advice or has a helpful idea what the reason for this behaviour is...
The method is called continuous every 30 seconds from inside a thread, looks for files to be transferred via a HTTP request to a web server (jboss) and brings them on their way. The server url itself is under my control.
Everything works fine ... until I stop the web server and force an 503 server error. So far so good. But after restarting the web server, I would expect, that the next call of the transfer method will end in success - but it does not. Every further try ends in a timeout exception and I have to restart the application to make it work again.
So my question is: where is the problem, when I want to connect to an uri after an earlier try has failed with error 503? It seems, that there is something cached, but what the hell should it be?
Many thanks for every hint you have.
Juergen
public static Boolean HttpUploadFile2(string url, string file)
{
HttpWebRequest requestToServer = null;
WebResponse response = null;
try
{
Logger.writeToLogFileCom(string.Format("Uploading {0} to {1}", file, url));
requestToServer = (HttpWebRequest)WebRequest.Create(url);
requestToServer. Timeout = 40000;
string boundaryString = "----SSLBlaBla";
requestToServer.AllowWriteStreamBuffering = false;
requestToServer.Method = "POST";
requestToServer.ContentType = "multipart/form-data;
boundary=" + boundaryString;
requestToServer.KeepAlive = false;
ASCIIEncoding ascii = new ASCIIEncoding();
string boundaryStringLine = "\r\n--" + boundaryString + "\r\n";
byte[] boundaryStringLineBytes = ascii.GetBytes(boundaryStringLine);
string lastBoundaryStringLine = "\r\n--" + boundaryString + "--\r\n";
byte[] lastBoundaryStringLineBytes = ascii.GetBytes(lastBoundaryStringLine);
// Get the byte array of the myFileDescription content disposition
string myFileDescriptionContentDisposition = String.Format(
"Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}",
"myFileDescription",
"A sample file description");
byte[] myFileDescriptionContentDispositionBytes
= ascii.GetBytes(myFileDescriptionContentDisposition);
string fileUrl = file;
// Get the byte array of the string part of the myFile content
// disposition
string myFileContentDisposition = String.Format(
"Content-Disposition: form-data;name=\"{0}\"; "
+ "filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n",
"myFile", Path.GetFileName(fileUrl), Path.GetExtension(fileUrl));
byte[] myFileContentDispositionBytes =
ascii.GetBytes(myFileContentDisposition);
FileInfo fileInfo = new FileInfo(fileUrl);
// Calculate the total size of the HTTP request
long totalRequestBodySize = boundaryStringLineBytes.Length * 2
+ lastBoundaryStringLineBytes.Length
+ myFileDescriptionContentDispositionBytes.Length
+ myFileContentDispositionBytes.Length
+ fileInfo.Length;
// And indicate the value as the HTTP request content length
requestToServer.ContentLength = totalRequestBodySize;
// Write the http request body directly to the server
using (Stream s = requestToServer.GetRequestStream())
{
//TIMEOUT OCCURED WHEN CALLING GetRequestStream
// Send the file description content disposition over to the server
s.Write(boundaryStringLineBytes, 0, boundaryStringLineBytes.Length);
s.Write(myFileDescriptionContentDispositionBytes, 0,
myFileDescriptionContentDispositionBytes.Length);
// Send the file content disposition over to the server
s.Write(boundaryStringLineBytes, 0, boundaryStringLineBytes.Length);
s.Write(myFileContentDispositionBytes, 0,
myFileContentDispositionBytes.Length);
// Send the file binaries over to the server, in 1024 bytes chunk
FileStream fileStream = new FileStream(fileUrl, FileMode.Open,
FileAccess.Read);
byte[] buffer = new byte[1024];
int bytesRead = 0;
Logger.writeToLogFileCom("writing data...");
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
s.Write(buffer, 0, bytesRead);
} // end while
fileStream.Close();
Logger.writeToLogFileCom("... finished, File closed");
// Send the last part of the HTTP request body
s.Write(lastBoundaryStringLineBytes, 0, lastBoundaryStringLineBytes.Length);
Logger.writeToLogFileCom("... finished, File closed");
} // end using
// Grab the response from the server. WebException will be thrown
// when a HTTP OK status is not returned
Logger.writeToLogFileCom("lese Response");
response = requestToServer.GetResponse();
StreamReader responseReader = new StreamReader(response.GetResponseStream());
string replyFromServer = responseReader.ReadToEnd();
response.Close();
if (Regex.Split(Regex.Split(replyFromServer, "content\\:RESPONSE\"\\>")[1], "\\</span\\>")[0].Equals("OK"))
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
Logger.writeToLogFileCom("Fehler im HTML Sender");
Logger.writeToLogFileCom(ex.Message);
Logger.writeToLogFileCom(ex.StackTrace);
}
finally
{
try
{
if (response != null)
{
response.Close();
}
}
catch (Exception ex) { }
}
return false;
}
I solved the problem.
I added an additional try / catch block inside the finally clause to call getResponse in every situation.
finally
{
try { response = requestToServer.GetResponse(); }
catch (Exception ex) { }
[...]

HttpWebRequest getRequestStream hangs on multiple runs

I've written some code to send and read text from a listener. This runs fine on the 1st and 2nd exchange, but on the 3rd send there's a long delay between calling GetRequestStream() and the actual writing of the data.
I've disposed the outstream on the send side, as well as the stream reader, and the input stream on the read side as recommended here: Does anyone know why I receive an HttpWebRequest Timeout?
And it still hangs on the 3rd attempt to send info. It definitely seems to be hanging at GetRequestStrean() in SendMessage():
public void SendMessage(string message)
{
HttpWebRequest request;
string sendUrl;
sendUrl = "http://" + termIPAddress + ":" + sendPort + "/";
Uri uri = new Uri(sendUrl);
Console.WriteLine("http://" + termIPAddress + ":" + sendPort + "/");
ServicePoint servicePoint = ServicePointManager.FindServicePoint(uri);
servicePoint.BindIPEndPointDelegate = new BindIPEndPoint(BindIPEndPointCallback);
servicePoint.ConnectionLeaseTimeout = 300;
request = (HttpWebRequest)WebRequest.Create(sendUrl);
request.KeepAlive = false;
request.Method = "POST";
request.ProtocolVersion = HttpVersion.Version11;
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add("SourceIP", localIPAddress);
request.Headers.Add("MachineName", localName);
requestStarted = true;
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(message);
request.ContentLength = buffer.Length;
try
{
using (Stream output = request.GetRequestStream())
{
output.Write(buffer, 0, buffer.Length);
output.Close();
request = null;
}
}
catch(WebException wE)
{
Console.WriteLine(wE.Message);
}
}
And this is the read portion :
public string GetMessage()
{
Console.WriteLine("Entering actual listener");
string s;
string sourceIP;
NameValueCollection headerList;
HttpListenerContext context = terminalListener.GetContext();
HttpListenerRequest request = context.Request;
headerList = request.Headers;
sourceIP = headerList.GetValues("SourceIP")[0];
termName = headerList.GetValues("MachineName")[0];
termIPAddress = sourceIP;
using (System.IO.Stream body = request.InputStream)
{
System.Text.Encoding encoding = request.ContentEncoding;
using (System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding))
{
s = reader.ReadToEnd();
body.Close();
reader.Close();
}
}
return termName + " : " + s;
}
I also tried to add an IP End Point bind but have to be honest, I don't fully understand this piece of the code:
private IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
{
int portNumber = Convert.ToInt32(sendPort);
IPEndPoint IEP = new IPEndPoint(IPAddress.Parse(localIPAddress), 0);
Console.WriteLine(Convert.ToString(IEP));
return IEP;
}
You just forgot to call HttpWebRequest.GetResponse and therefore run out of connection limit.
So, you should change your code as follows:
try
{
using (Stream output = request.GetRequestStream())
output.Write(buffer, 0, buffer.Length);
var response = request.GetResponse() as HttpWebResponse;
//TODO: check response.StatusCode, etc.
}
catch(WebException wE)
{
Console.WriteLine(wE.Message);
}
Also, in some cases you might want to adjust default connection limit:
ServicePointManager.DefaultConnectionLimit
Or use persistent connections:
HttpWebRequest.KeepAlive

webservice request issue with dynamic request inputs

try
{
const string siteURL = "http://ops.epo.org/2.6.1/soap-services/document-retrieval";
const string docRequest = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'><soap:Body><document-retrieval id='EP 1000000A1 I ' page-number='1' document-format='SINGLE_PAGE_PDF' system='ops.epo.org' xmlns='http://ops.epo.org' /></soap:Body></soap:Envelope>";
var request = (HttpWebRequest)WebRequest.Create(siteURL);
request.Method = "POST";
request.Headers.Add("SOAPAction", "\"document-retrieval\"");
request.ContentType = " text/xml; charset=utf-8";
Stream stm = request.GetRequestStream();
byte[] binaryRequest = Encoding.UTF8.GetBytes(docRequest);
stm.Write(binaryRequest, 0, docRequest.Length);
stm.Flush();
stm.Close();
var memoryStream = new MemoryStream();
WebResponse resp = request.GetResponse();
var buffer = new byte[4096];
Stream responseStream = resp.GetResponseStream();
{
int count;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
} while (count != 0);
}
resp.Close();
byte[] memoryBuffer = memoryStream.ToArray();
System.IO.File.WriteAllBytes(#"E:\sample12.pdf", memoryBuffer);
}
catch (Exception ex)
{
throw ex;
}
The code above is to retrieve the pdf webresponse.It works fine as long as the request remains canstant,
const string docRequest = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'><soap:Body><document-retrieval id='EP 1000000A1 I ' page-number='1' document-format='SINGLE_PAGE_PDF' system='ops.epo.org' xmlns='http://ops.epo.org' /></soap:Body></soap:Envelope>";
but how to retrieve the same with dynamic requests. When the above code is changed to accept dynamic inputs like,
[WebMethod]
public string DocumentRetrivalPDF(string docid, string pageno, string docFormat, string fileName)
{
try
{
........
.......
string docRequest = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'><soap:Body><document-retrieval id=" + docid + " page-number=" + pageno + " document-format=" + docFormat + " system='ops.epo.org' xmlns='http://ops.epo.org' /></soap:Body></soap:Envelope>";
......
........
return "responseTxt";
}
catch (Exception ex)
{
return ex.Message;
}
}
It return an "INTERNAL SERVER ERROR:500" can anybody help me on this???
Internal Server Error simply means there's something wrong on the server. It usually means that the server has thrown an exception which was not handled.
Look in the Windows Event logs for an answer. In particular, look in the Application event log.
By the way, your code is pretty bad.
All the IDisposable classes should be instantiated in using blocks.
"throw ex" just messes up your stack. Get rid of that try/catch entirely.

Categories

Resources