I want to make a POST to a php-written Web Service that sits on a secure connection. The following code is just a test console app I wrote after a few hours of trial and error. Essentially, I found out a few different methods to use HttpWebRequest, but all of them are the same thing.
Testing my URI with 'http' on a web browser, should return a blank html (with an empty body). This works OK in a browser and in my code.
I went ahead a tried http://www.google.com and I got google… (as expected). The problem arises when I change the URI from http to https. Testing my URI with 'https' on a web browser, returns the same blank html (this is expected). But when I try the same URI in code, I get a 404 Not Found.
Here's the simple code (and the URI) (uncomment the second one to try https):
try
{
string lcUrl = "http://servicios.mensario.com/enviomasivo/apip/";
//string lcUrl = "https://servicios.mensario.com/enviomasivo/apip/";
// *** Establish the request
HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(lcUrl);
// *** Set properties
loHttp.Timeout = 10000; // 10 secs
loHttp.Method = "POST"; // I added this for testing, but using GET or commenting this out doesn't change anything.
// Retrieve request info headers ******** HERE I GET THE EXCEPTION **********
HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse();
// All this code only works when lcUrl is NOT https.
Encoding enc = Encoding.GetEncoding(1252); // Windows default Code Page
StreamReader loResponseStream = new StreamReader(loWebResponse.GetResponseStream(), enc);
string lcHtml = loResponseStream.ReadToEnd();
loWebResponse.Close();
loResponseStream.Close();
}
catch ( WebException ex )
{
if ( ex.Status == WebExceptionStatus.ProtocolError )
{
HttpWebResponse response = ex.Response as HttpWebResponse;
if ( response != null )
{
// Process response
Console.WriteLine(ex.ToString());
}
}
}
Console.Read();
return;
The exception is:
System.Net.WebException: The remote server returned an error: (404) Not Found. at System.Net.HttpWebRequest.GetResponse()
note: The http url shown here is the real one I have to use, it doesn't belong to me but to another company.
If the response were OK, this is what lcHtml should contain:
<html>
<head>
<title></title>
</head>
<body>
</body>
</html>
Since I googled and StackOverflowed a lot before posting this question, I found out a few ideas. One is to add the "ignore certificates" code:
System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate( object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors )
{
return true; // **** Always accept
};
That doesn't seem to change anything.
Other user said that the SSL Protocol Type might be wrong… so I tried with these two to no avail:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
Any ideas?
UPDATE I went back and created a simple console app. The only code is this:
WebRequest req = WebRequest.Create("http://servicios.mensario.com/enviomasivo/apip/");
WebResponse resp = req.GetResponse();
That works. No error.
However, if I change the URI to https:
WebRequest req = WebRequest.Create("https://servicios.mensario.com/enviomasivo/apip/");
WebResponse resp = req.GetResponse();
I get an error (go ahead and try it).
However this php code seems to work. The only relevant line of code that I see different is:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
The comment, in spanish says: "With this we can ignore the SSL Cert".
I think that's the key. But the
System.Net.ServicePointManager.ServerCertificateValidationCallback…
…stuff, doesn't seem to have the same effect.
Thanks in advance.