Simple HttpWebRequest over SSL (https) gives 404 N

2019-06-20 16:14发布

问题:

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.

回答1:

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.



回答2:

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



回答3:

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?