Why does HttpWebRequest fail the first time and then works OK? - asp.net

I am truing to integrate fusemail in asp.net 2.0. I am using HttpWebRequest for requesting the API pages. It has recently come to my notice that HttpWebRequest fails the first time and then continues and subsequent requests succeed.
say ( i know if i use goto it is a bad programming approach) if i use this code
retry:
try
{
Uri uri = new Uri("http://www.fusemail.com/api/request.html");
if (uri.Scheme == Uri.UriSchemeHttp)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.PreAuthenticate = true;
request.Method =
WebRequestMethods.Http.Post;
//request.ReadWriteTimeout = System.Threading.Timeout.Infinite;
//request.Timeout = System.Threading.Timeout.Infinite;
request.ContentLength = data.Length;
request.ContentType =
"application/x-www-form-urlencoded";
//request.UserAgent = Request.UserAgent;
request.UserAgent = "Mozilla/4.0";
request.KeepAlive = false;
request.ServicePoint.Expect100Continue = true;
//request.Accept = "Accept: text/html,application/xhtml+xml,application/xml";
StreamWriter writer = new StreamWriter(request.GetRequestStream());
writer.Write(data);
writer.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string tmp = reader.ReadToEnd();
response.Close();
//Response.Write(tmp);
if (!String.IsNullOrEmpty(tmp))
{
return tmp;
}
}
return String.Empty;
}
catch (WebException ex)
{
goto retry;
}
it works after failing once. i am writing to a text file in case of an error and after i failed request it works the second time. I am using ASP.Net 2.0 and the website is hosted on IIS 7 with Windows Server 2008 Standard. Also pinging the API address it fails the first time and then responds
C:\>ping 67.207.202.118
Pinging 67.207.202.118 with 32 bytes of data:
Reply from 192.168.0.253: **Destination host unreachable**.
Reply from 67.207.202.118: bytes=32 time=218ms TTL=49
Reply from 67.207.202.118: bytes=32 time=218ms TTL=49
Reply from 67.207.202.118: bytes=32 time=217ms TTL=49
Ping statistics for 67.207.202.118:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 217ms, Maximum = 218ms, Average = 217ms
The first time it fails in HttpWebRequest it fails with this error
System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 67.207.202.118:80
Is there an authentication issue the first time?. i read on some forums it first sends a 401 Unauthorized and then it can connect. I am unable to verify this using Fiddler.
Is there anything wrong with IIS configuration?

This is not a programming issue at all, I have faced a similar problem later and it was a network configuration problem due to ISA server / Firewall settings.
You have to contact your network administrator to check this issue.
I wish this helped you.
Yours,
Mohamed Kamal Elbeah
Senior .Net Developer

I recently came by this same issue. The solution in my case involved my testing environment, since I had multiple Ethernet adapters connected to my computer. While you may have a different IP for each of your Ethernet adapters, if they are all assigned to the same subnet this may cause a problem. The TCP connection is only attempted using one NIC at a time. So in my case, on the first try it would attempt the connection on one adapter that was not connected to my remote host, then on the second try it would connect using the second adapter which was connected. - Hope this helps someone.

Related

Httpwebrequst returns 500 internal server error while sending jsonconvert.serializeobject

We are sending JsonConvert.SerializeObject(lstobject); to the URL here. lstobject is a large list sent to the url.error also returned after 3 minutes to log error how to make webrequest to wait 5 minutes.
var httpWebRequest = (HttpWebRequest)WebRequest
.Create(ConfigurationManager.AppSettings["JsonPayloadPostUrl"]
.ToString());
httpWebRequest.Timeout = 1000000;
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(jsonPayload);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
}
Ee have used httpWebRequest.Timeout = 1000000; but the server is unable to send request back in less than 5 minutes. How to make request to wait for server for response ?
I might be missing something reading your question, but HTTP 500 server error means that the server has provided a response, saying it encountered some internal issue. So you cannot prevent it by setting a bigger timeout on the Request side.
Following https://www.w3.org/Protocols/HTTP/HTRESP.html
Internal Error 500
The server encountered an unexpected condition which prevented it from
fulfilling the request.
I would say either your request is not properly built, or the server has some application-side issue.
Coming back to the timeout setting way, I think it looks properly. Please note that this time might be taking into account topics like DNS name resolution etc. which in turn might require a bit more time than it seems in the first place. This shouldn't be a problem in your case though, looking at the value you are trying to set.

HttpWebResponse: The operation has timed out

Im setting up a project on a new dev machine. (Win7, vs2k12)
The code works fine on the production machine.
This code gives me "The operation has timed out".
var request = (HttpWebRequest) System.Net.WebRequest.Create(url);
request.Timeout = TimeoutMilliSeconds;
request.Method = "GET";
request.UserAgent = "X";
var response = (HttpWebResponse)request.GetResponse();
The url works fine when I call it from the browser.
I know which ports are open for incoming traffic.
Im using IIS express.
How do I proceed?
Thanks
Set the ReadWriteTimeout property.For details see a link:
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.readwritetimeout.aspx
request.ReadWriteTimeout = 5000; //Increase Time as your requirement.

Email using System.Net.Mail through Google Apps Timing out

I have a ASP.NET 4.0 web application, which the HR team uses to send out surveys to employees. Since we use a Google Apps, I am trying to send these survey emails through the Google Apps Account.
I have used the following settings to send out emails.
Host - smtp.gmail.com
Port - 587
EnableSsl=true
along with my username and password.
This is the code for sending out emails.
using (SmtpClient smtp = new SmtpClient())
{
smtp.Timeout = 0;
smtp.Send(message);
}
The settings are in the web.config and are read from there.
Now my issue..
The hr team selects multiple users to send the survey to. They could just select 1 or maybe up to 100 at a time to send out surveys. Since each survey link has to be different, I iterate the list of users and email them.
Now after the application send out a maximum of 12 emails, it stops sending out any more. The next email it tries to send it throws an error.
Message = The operation has timed out.
Status Code =GeneralFailure
Stack Trace = at System.Net.Mail.SmtpClient.Send(MailMessage message)
at ABC.Business.Mail.SendMail(MailMessage message, String& errorMessage)
Then onwards if I retry again it throws an error
Message = Failure sending mail.
Status Code =GeneralFailure
Stack Trace = at System.Net.Mail.SmtpClient.Send(MailMessage message)
at ABC.Business.Mail.SendMail(MailMessage message, String& errorMessage)
If its come to this state, the only way out is to retart IIS. If I restart IIS, it starts working fine again for the next 12 odd.
What could be the issue? Please help.
You shouldn't set the Timeout to zero.
Its default is 100,000mS (100 seconds), try to leave it at that at least.
System.Net.Mail only supports "Explicit SSL".
Explicit SSL
System.Net.Mail only supports "Explicit SSL". Explicit SSL starts as unencrypted on port 25, then issues a STARTDLS and switches to an Encrypted connection. See RFC 2228.
Explicit SLL would go something like: Connect on 25 -> StartTLS (starts to encrypt) -> authenticate -> send data
If the SMTP server expects SSL/TLS connection right from the start then this will not work.
Implicit SSL
There is no way to use Implicit SSL (SMTPS) with System.Net.Mail. Implicit SSL would have the entire connection is wrapped in an SSL layer. A specific port would be used (port 465 is common). There is no formal RFC covering Implicit SSL.
Implicit SLL would go something like: Start SSL (start encryption) -> Connect -> Authenticate -> send data
This is not considered a bug, it’s a feature request. There are two types of SSL authentication for SMTP, and we only support one (by design) – Explicit SSL.
Demo Code:
*
protected void Btn_SendMail_Click(object sender, EventArgs e)
{
try
{
var fromAddress = "xyz#gmail.com";
var toAddress = "abc#gmail.com";
const string fromPassword = "xxxxxxxx";
string subject = "Sending Demonstration";
string body = "From: " + txtFrom.Text + "\n";
var smtp = new System.Net.Mail.SmtpClient();
{
smtp.Host = "smtp.gmail.com";
smtp.Port = 25;
smtp.EnableSsl = true;
smtp.Credentials = new NetworkCredential(fromAddress, fromPassword);
}
smtp.Send(fromAddress, toAddress, subject, body);
Response.Write("<script language=javascript> alert('send')</script>");
}
catch (Exception ex)
{
txtBody.Text = ex.Message;
}
}
*
This Code Is Working Without Any Error!!!!
Chris, TimeOut makes ASP.NET application to wait for the request to perform before it shutting down automatically. So, If you give timeOut as zero, ASP.NET will not wait for the request to perform and it will throw error as operation has timed out.
TimeOut should be atleast 180 seconds.
Thanks.

HTTP Connection Parameters

I am using the HTTP Connection in the following way:
HttpConnection _httpConnection = null;
try {
_httpConnection = (HttpConnection)Connector.open(_url);
} catch(Exception e) { }
byte [] postDataBytes = _postData.getBytes();
_httpConnection.setRequestMethod(HttpConnection.POST);
_httpConnection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Configuration/CLDC-1.0");
_httpConnection.setRequestProperty("Content-Language", "en-US");
_httpConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
_httpConnection.setRequestProperty("Connection", "close");
_httpConnection.setRequestProperty("Content-Length", Integer.toString(_postData.getBytes().length));
os = _httpConnection.openOutputStream();
os.write(postDataBytes);
os.flush();
This HTTP Connection requires parameters to successfully open. For example on a WIFI network, it requires the ";deviceside=true;interface=wifi" to be added to the URL.
The problem is for the EDGE connection. Each country requires different parameters to be added. For example in lebanon it requires ";deviceside=false" but in KSA if i add this parameter the connection will not open. In USA it needs different types of parametes. The question is how to establish an HTTP connection for all the countries with the same parameters. So that the application will successfully have an internet connection no matter where it is downloaded.
Welcome to the confusing world of network transports on BlackBerry! You will want to start with the article Connecting your BlackBerry - http and socket connections to the world.
Here is a simple example for "just give me a connection" (note, you will need to add appropriate error handling; also, myURL in the code below should have no connection descriptor info appended to it):
ConnectionFactory factory = new ConnectionFactory();
ConnectionDescriptor descriptor = factory.getConnection(myURL);
if (descriptor != null) {
_httpConnection = (HttpConnection) descriptor.getConnection();
...
}
Try using to use the method reffered in this link melick-rajee.blogspot.com and use it like
_url = "http://www.example.com";
_httpConnection = (HttpConnection)Connector.open(_url + getConnectionString());
You will have to sign the application to use this else the application will show exception.
To sign your application just go here Code Signing Keys
To use the connectionFactory, seems you need to set BisBOptions.
Try this:
connFact = new ConnectionFactory();
connFact.setTransportTypeOptions(TransportInfo.TRANSPORT_BIS_B,
new BisBOptions("mds-public"));

WebRequest problem, response before request-body

I'am using the WebRequest class in .net and POST data to a server which is responding with a Response.
The wierd thing is that its working when I started fiddler to analyze my network traffic, but without fiddler it isn't.
So i started to analyze the package which is sent to and from my computer with WireShark. With in this program its simple to follow the TCP-stream. So when I had fiddler on, I can see the correct Request-header/body is sent, and gets the Response-header/body. The strange part is when i dont use fiddler the Request-header is sent, then i´ve got the Response-header/body, and finally the request-body in the end of the TCP-stream.
Here is my code i've been elaborating:
string lcUrl = "http://XX.XX.XXX.XX";
// *** Establish the request
HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(lcUrl);
string lcPostData = testdata;
loHttp.Method = "POST";
byte [] lbPostBuffer = System.Text.Encoding.GetEncoding(1252).GetBytes(lcPostData);
loHttp.ContentLength = lbPostBuffer.Length;
loHttp.Credentials = CredentialCache.DefaultCredentials;
//loHttp.SendChunked = true;
loHttp.ServicePoint.Expect100Continue = false;
Stream loPostData = loHttp.GetRequestStream();
loPostData.Write(lbPostBuffer, 0, lbPostBuffer.Length);
loPostData.Close();
HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse();
Encoding enc = System.Text.Encoding.GetEncoding(1252);
StreamReader loResponseStream = new StreamReader(loWebResponse.GetResponseStream(), enc);
string lcHtml = loResponseStream.ReadToEnd();
loWebResponse.Close();
loResponseStream.Close();
Please use following code. Seems that you have problems with time when underlying stream are send to remote server.
string lcUrl = "http://XX.XX.XXX.XX";
// *** Establish the request
HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(lcUrl);
string lcPostData = testdata;
loHttp.Method = "POST";
byte[] lbPostBuffer = System.Text.Encoding.GetEncoding(1252).GetBytes(lcPostData);
loHttp.ContentLength = lbPostBuffer.Length;
loHttp.Credentials = CredentialCache.DefaultCredentials;
//loHttp.SendChunked = true;
loHttp.ServicePoint.Expect100Continue = false;
using (Stream loPostData = loHttp.GetRequestStream())
{
loPostData.Write(lbPostBuffer, 0, lbPostBuffer.Length);
}
string lcHtml;
using (HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse())
{
Encoding enc = System.Text.Encoding.GetEncoding(1252);
using (StreamReader loResponseStream = new StreamReader(loWebResponse.GetResponseStream(), enc))
{
lcHtml = loResponseStream.ReadToEnd();
}
}
// Perform processing of data here....
Also I could suggest you add following code in the app.config file for your application. This is helps when server returns response that not conforms with way how .NET handle HTTP request.
<configuration>
<system.net>
<settings>
<httpWebRequest
useUnsafeHeaderParsing="true"
/>
</settings>
</system.net>
</configuration>
I have a suspicion that the client is waiting for the "HTTP/1.1 100 continue" response from the server. This is how it works. When you are posting data to the server, sometimes the server might not be ready to accept the data just yet. For eg, it wants to authenticate the client first.
So, when you send a POST request, the client just sends the request headers, with an "Expect: 100-continue" appended.
POST /url HTTP/1.1
Server: Server-name/fqdn
Content-Length: 100
Expect: 100-continue
If the server is ready to receive the data it responds with:
HTTP/1.1 100 continue
Server: server-name/fqdn
Now, the client can send the data.
However if the server is not ready to receive the data, and wants to authenticate the client, it will respond with a different status code.
If you post your wireshark trace to pastebin.com I can verify, but I suspect this is what is happening.
The reason you dont see this in fiddler might be that fiddler is using HttpListener to listen to HTTP request, and HTTP listener hides the intermediate response like 100-continue from the app (in this case fiddler).

Resources