views:

4743

answers:

4

Hi,

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.

A: 

You could try the trick described here: http://oregonstate.edu/~reeset/blog/archives/166

thijs
Thanks. I have just tried but it didn't change anything. It's actually interesting to note that the method described there, it's now marked as Obsolete and the callback is the way to go.This: ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
Martín Marconcini
hmm too bad it didn't do anything. Do you also see the 404 in the web server logfiles?
thijs
I don't have access to the web server logfiles :( It's not my webserver.I think that I must be doing something terribly wrong here… cannot be that weird.
Martín Marconcini
A: 

This doesn't look like it's a problem with the code, since the URL you gave seems to have a valid SSL cert anyway.

Trying your two-line snippet with "https://www.google.com" works, so I suggest setting up a web debugging proxy like Fiddler to compare the HTTP Request fields when using HTTP and HTTPS on servicios.mensario.com/enviomasivo/apip. Are you using a reverse proxy on that site?

Hi maxam, I'm not running any sort of proxy. Have you tried running the two-line snippet against https://servicios.mensario.com/enviomasivo/apip/ ? Do you get a 404?Thanks.
Martín Marconcini
Hi, I've installed Fiddler. With the "two-line" vs HTTPS (I get the exception), the result appears to be ok, however fiddler says that it's encrypted. If I decrypt (in fiddler) the result seems ok:HTTP/1.1 404 /enviomasivo/apip/Set-Cookie: JSESSIONID=13B63930D2DBA0520FB602D8006B6C44; Path=/enviomasivo; SecureContent-Type: text/html;charset=ISO-8859-1Date: Tue, 21 Apr 2009 15:54:00 GMTServer: Apache-Coyote/1.1Content-Length: 61<html><head><title></title></head><body></body></html>
Martín Marconcini
+5  A: 

After some experimentation using fiddler and firefox, it seems that your URL is the problem. For me, this gives a 404:

https://servicios.mensario.com/enviomasivo/apip/

and this doesn't:

https://servicios.mensario.com/enviomasivo/apip

Note, the ending slash. Also, the php sample you posted doesn't have the ending slash either.

Erv Walter
Oh my, you know, I've asked the programmer (of the service) for the *exact* url six times. He sent me an email with the slashed version. I tried once with the non slashed but my code was wrong and "to stay in the safe side" i left the slash, as suggested by the programmer. But… after changing that, things started to work! You're my hero! THanks a lot!!!
Martín Marconcini
A: 

I am facing the same problem, I am trying to get a response from a file. How do i solve this. The slash '/' will not work in my case as i try to hit a complete aspx page.

Prabodh