Mono Apache2 HttpWebRequest crashes with "The request timed out" - c#

I am using a payment gateway API in my ASP.Net application. When testing in MonoDevelop with XSP the application works. When I configure it to run in apache2 with mod_mono the code keeps crashing with a timeout error.
I am stumped as to what could change with hosting in Apache instead of XSP. Anyways below is the code that is timing out:
private string SubmitXml(string InputXml)
{
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(_WebServiceUrl);
webReq.Method = "POST";
byte[] reqBytes;
reqBytes = System.Text.Encoding.UTF8.GetBytes(InputXml);
webReq.ContentType = "application/x-www-form-urlencoded";
webReq.ContentLength = reqBytes.Length;
webReq.Timeout = 5000;
Stream requestStream = webReq.GetRequestStream();
requestStream.Write(reqBytes, 0, reqBytes.Length);
requestStream.Close();
HttpWebResponse webResponse = (HttpWebResponse)webReq.GetResponse();
using (StreamReader sr = new StreamReader(webResponse.GetResponseStream(), System.Text.Encoding.ASCII))
{
return sr.ReadToEnd();
}
}
The code is crashing on the line: Stream requestStream = webReq.GetRequestStream();
The error returned is:
The request timed out
Description: HTTP 500. Error processing request.
Stack Trace:
System.Net.WebException: The request timed out at
System.Net.HttpWebRequest.GetRequestStream () [0x0005f] in
/private/tmp/monobuild/build/BUILD/mono-2.10.9/mcs/class/System/System.Net/HttpWebRequest.cs:746
at TCShared.PxPay.SubmitXml (System.String InputXml) [0x00048] in
/Users/liam/Projects/techcertain/techcertaincsharp/Components/TCShared/PaymentGateways/Client/PxPay.cs:85
at TCShared.PxPay.GenerateRequest (TCShared.RequestInput input)
[0x00015] in
/Users/liam/Projects/techcertain/techcertaincsharp/Components/TCShared/PaymentGateways/Client/PxPay.cs:69
In my Web.Config I have the following as the request timeout:
<httpRuntime executionTimeout="43200" maxRequestLength="104856" requestValidationMode="2.0" />
I have tried changing the Timeout value on the HttpWebRequest but it still is timing out.
What is causing this to happen and how can I fix it?

I managed to find out why I was experiencing this problem. It is completely unrelated to the use of Apache.
I am using Npgsql for database access to Postgresql. Npgsql comes with two dlls (Npgsql.dll and Mono.Security.dll). For some unknown reason Mono.Security.dll causes the HttpWebRequest to timeout when running on Mono.
Anyways Mono.Security.dll isn't needed when running on Mono because it is already included in the Mono framework. So after removing the Mono.Security dll from my bin directory HttpWebRequest's are now working.
Full credit goes to this post here http://mono.1490590.n4.nabble.com/The-request-timed-out-at-HttpWebRequest-EndGetResponse-td2218213.html .

Related

https request fails only in .net web app

I am trying to patch a .net web application that after years of working started failing to get UPS shipping quotes, which is impacting web business dramatically. After much trial and error, I found the following code that works just fine in a console application:
static string FindUPSPlease()
{
string post_data = "<xml data string>";
string uri = "https://onlinetools.ups.com/ups.app/xml/Rate";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
byte[] postBytes = Encoding.ASCII.GetBytes(post_data);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postBytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
// get response and send to console
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());
Console.WriteLine(response.StatusCode);
return "done";
}
This runs in Visual Studio just fine and gets a nice little response from UPS that the XML is, of course, malformed.
But, if I paste this function into the web application without changing a single character, an exception is thrown on request.GetRequestStream():
Authentication failed because the remote party has closed the transport stream.
I tried it in a couple of different place in the application with the same result.
What is there about the web application environment that would affect the request?
It turns out to be a TLS issue. I guess the console app uses a higher protocol by default than the web application, although none was specified. So, all you have to do is add the following line(s) of code sometime prior to making the request:
using System.Net;
...
System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
That was all it took, though I spent an enormous amount of getting there.
Here is the response from UPS on the issue:
Effective January 18, 2018, UPS will only accept TLS 1.1 and TLS 1.2 security protocols... 100% of requests from customers who are on TLS 1.0 while using production URLS (onlinetools.ups.com/tool name) will be rejected.
Anyway, hope this helps someone.
Jim
Can you try setting the Credentials to your request object like following.
request.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
Try setting the default credentials or check if there is any proxy server set and pass it like in the example below.
The example is given for WebClient.
I was having problem with setting Default Credential, as proxy was enabled on the server. So i passed the proxy URL and port with credentials which can access it.
using (System.Net.WebClient web = new System.Net.WebClient())
{
//IWebProxy defaultWebProxy = WebRequest.DefaultWebProxy;
//defaultWebProxy.Credentials = CredentialCache.DefaultCredentials;
//web.Proxy = defaultWebProxy;
var proxyURI = new Uri(string.Format("{0}:{1}", proxyURL, proxyPort));
//Set credentials
System.Net.ICredentials credentials = new System.Net.NetworkCredential(proxyUserId, proxyPassword);
//Set proxy
web.Proxy = new System.Net.WebProxy(proxyURI, true, null, credentials);
web.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
var result = web.UploadString(URL, "");
return result;
}

Error 500 Trying to Connect to NetSuite RESTlet using C#

I'm trying to build a connector between a credit card processor and a client's NetSuite account to help automate their reconciliation process. Not having any trouble pulling info from their card processor, except occasionally when it has its own error 500. Still trying to find a way to better handle it than what I'm doing.
Anyway, the problem is occurring when I try to connect to the RESTlet in their NetSuite account. I can't seem to get it to properly connect, and all I get are error 500 responses. The problem doesn't seem to be the RESTlet as I can communicate with it fine when using tools like "Send HTTP Tool" to test it out. This is the code I'm using currently:
JavaScriptSerializer jss = new JavaScriptSerializer();
String content = jss.Serialize(rd);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(this.nsURL);
req.ContentType = "application/json";
req.ContentLength = content.Length;
req.Method = "POST";
WebHeaderCollection headers = new WebHeaderCollection();
headers.Add("User-Agent-X", "SuiteScript-Call");
headers.Add("Authorization", String.Format("NLAuth nlauth_account={0},nlauth_email={1},nlauth_signature={2},nlauth_role={3}",
this.nsAccount, this.nsEmail, this.nsPassword, this.nsRole));
req.Headers = headers;
using (StreamWriter requestWriter = new StreamWriter(req.GetRequestStream()))
{
requestWriter.Write(content);
}
HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); // error occurs here
Stream stream = resp.GetResponseStream();
using (StreamReader reader = new StreamReader(stream))
{
String response = reader.ReadToEnd();
Console.WriteLine(response);
}
And this is the error recorded:
[System.Net.WebException] The remote server returned an error: (500) Internal Server Error.
The error occurs at the point I try to retrieve the response from the HttpWebRequest object. I have tried sending the data instead as a byte array, but that causes a different error at the point I actually write the data to the connection. The RESTlet is also setup to log the data it receives upon being called, but this error is occurring before the RESTlet function can even be triggered.
I've spent too much time trying various different "fixes" to get this to work with no luck.
---- EDIT ----
Forgot to mention that I'm using Visual Studio 2010 Pro and targeting .NET 4.

wowza streaming c# HTTP get method for livestreamrecord

Hello I need some help with livestreamrecord recording via http url c# calls,
I can start and stop a stream recording using:
http://[username]:[password]#[wowza-ip-address]:8086/livestreamrecord?app=live&streamname=myStream&action=startRecording
When inputting it directly in to a browser or when I redirect my webpage to it from code, but when I try to do the same from c# on a webpage nothing happens.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://[username]:[password]#[wowza-ip-address]:8086/livestreamrecord?app=live&streamname=myStream&action=startRecording);
request.Method = "GET";
request.Proxy = new WebProxy("[wowza-ip-address]", 8086);
request.Credentials = new NetworkCredential("[username]", "[password]");
request.ContentType = "application/x-www-form-urlencoded";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stm = response.GetResponseStream();
When I first tried to set it up I kept getting 401 unauthorized error which the code above no long throws, but now I'm stuck as no error is thrown and still no recording is started.
The response returns:
<html><head><title>Wowza Streaming Engine 4 Perpetual Edition 4.0.1 build10615</title></head><body>Wowza Streaming Engine 4 Perpetual Edition 4.0.1 build10615</body></html>
Which indicates it is not reaching the livestreamrecord page.
Ben
Sovled the problem, thier was a 302 redirect on the request which was producing the 401 unauthorized responses. Adding:
request.AllowAutoRedirect = false;
and removing:
request.Proxy = new WebProxy("[wowza-ip-address]", 8086);
Resolved the problem.
With Proxy in, it didn't throw an error but also didn't record. Removing Proxy allowed the record command to work but throw the 401 response which was then resolved by setting AllowAutoRedirect to false.

HttpWebRequest.GetResponse: "The underlying connection was closed: An unexpected error occurred on a receive."

I've written a C# Windows service (.NET Framework 3.5, C# 3.0) that posts files & HTML form information to a remote server, and then stores the XML server response in a database. Here is the main chunk of pertinent code:
HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;
request.ProtocolVersion = HttpVersion.Version10;
request.KeepAlive = false;
request.Timeout = 600000;
request.ReadWriteTimeout = 600000;
request.Method = "POST";
request.ContentType = contentType;
request.UserAgent = userAgent;
request.CookieContainer = new CookieContainer();
request.ContentLength = formData.Length;
using (Stream requestStream = request.GetRequestStream())
{
// Push it out there
requestStream.Write(formData, 0, formData.Length);
requestStream.Close();
}
return request.GetResponse() as HttpWebResponse;
My service works properly for all small files, but I get the following error when I try to send larger files (8-9 MB).
The underlying connection was closed: An unexpected error occurred on a receive.
I looked at the outgoing request using Fiddler, and was able to glean the following info:
HTTP/1.1 504 Fiddler - Receive Failure
Content-Type: text/html
Connection: close
Timestamp: 12:25:04.067
ReadResponse() failed: The server did not return a response for this request.
The failure occurs ~7 minutes after I call request.GetResponse(). Is there any way to identify who shut down the connection? And is there anything else I should try on my end to resolve this issue? Thanks in advance!
Since you mention it working for small files, but not larger, I'd suggest checking the max file upload size on the server. I believe the default is 4mb. http://support.microsoft.com/kb/295626
EDIT: Noticed the link above is somewhat out of date. Here's one for iis7: http://www.cyprich.com/2008/06/19/fixing-file-upload-size-limit-in-iis-7/

.NET Web Service receive HTTP POST request (500) Internal Server Error

I am currently writing a C# web service which has several methods, one of which has to receive HTTP POST requests. The first thing i have done is alter the web.config file in the web service project as below.
<webServices>
<protocols>
<add name="HttpSoap"/>
<add name="HttpPost"/>
<add name="HttpPostLocalhost"/>
<add name="Documentation"/>
</protocols>
</webServices>
I can run the web service locally and when i click on the method in the browser, i can see it handles HTTP POST requests and accepts args=string, as my signature of the web method accepts one string parameter named args. I am then testing this via a test ASP.NET app using the code below to fire the HTTP POST request.
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(ConfigurationManager.AppSettings["PaymentHubURL"].ToString());
request.KeepAlive = false;
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
StringBuilder sb = new StringBuilder();
sb.Append("message_type=");
sb.Append(HttpUtility.UrlEncode("Txn_Response"));
byte[] bytes = UTF8Encoding.UTF8.GetBytes(sb.ToString());
request.ContentLength = bytes.Length;
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(bytes, 0, bytes.Length);
}
string test;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
StreamReader reader = new StreamReader(response.GetResponseStream());
test = reader.ReadToEnd();
}
But when i run this i get "The remote server returned an error: (500) Internal Server Error". If i remove the parameter, by removing the stringbuilder and byte code, as well as having no parameter in the web service, it works. So it is obviously a problem with the parameters. I actually want to send more data, and was using a string[] parameter in the web service, but this also failed.
Can anyone help??
I would suggest that you reconsider your approach. Microsoft has written pretty awesome libraries for consuming web services, but there are two ways to do it - "add web reference" and "add service reference".
In your case, it seems you have an "asmx web service" so I would recommend that you add a "web reference" to you project in visual studio. This is assuming you are using visual studio.
After you add this web reference, you can create your client by "new"-ing it. You can the execute any web method on this client. This is the easiest way to consume web services. You do not have to deal with any http complications.
Hope this helps.
I can guess you are building the HttpPost request wrongly.
Try to use the code showed at the link below to create your request:
http://msdn.microsoft.com/en-us/library/debx8sh9.aspx
Or probabily the response doesn't contain unicode char value
try to copy and paste this code to get the response
System.Text.Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader objSR;
webResponse = (HttpWebResponse)response.GetResponse();
StreamReader reader = webResponse.GetResponseStream();
objSR = new StreamReader(objStream, encode, true);
sResponse = objSR.ReadToEnd();

Categories