C# Authentication failed because the remote party has closed the transport stream

Taco2 picture Taco2 · Mar 25, 2017 · Viewed 43.4k times · Source

I want to point out that I have searched a lot for this without a solution. So, I've created a loop that will go throw listBox2 that contains links, each time creating a http GET request in order to access the full source code.

My code:

 private void button4_Click(object sender, EventArgs e)
    {
        try
        {
            for (int i = 0; i < listBox2.Items.Count; i++)
            {
                code(listBox2.Items[i].ToString() + "\'");
                //await PutTaskDelay();
                //Console.WriteLine(listBox2.Items[i].ToString());
                if (VarrileKeeper.s.ToLower().Contains("mysql"))
                {
                    Console.WriteLine("possitive " + listBox2.Items[i].ToString());
                }
            }
        }
        catch (Exception Fejl)
        {
            Console.WriteLine(Fejl);
        }
    }


 public static String code(string Url)
    {

        System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };


        HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(Url);
        myRequest.MaximumAutomaticRedirections = 4;
        myRequest.MaximumResponseHeadersLength = 4;
        myRequest.Credentials = CredentialCache.DefaultCredentials;

        myRequest.Method = "GET";

        WebResponse myResponse = myRequest.GetResponse();


        StreamReader sr = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
        string result = sr.ReadToEnd();
        sr.Close();
        myResponse.Dispose();
        myResponse.Close();
        VarrileKeeper.s = result;
        return result;
    }

The error below is triggered when the loop hits various of urls for example (http://www.memphremagog.org/fr/lexique.php?id=32). The weird thing is that if I remove the loop and make a http GET reqeust to that site everything works just fine.

A first chance exception of type 'System.Net.WebException' occurred in System.dll System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Authentication failed because the remote party has closed the transport stream.

I don't think it's a problem with the certificate because otherwise I would still get an error on http://www.memphremagog.org/fr/lexique.php?id=32 when I removed the loop.

Any suggestions are appreciated.

Answer

Larry Dukek picture Larry Dukek · Mar 31, 2017

The zvoxaudio.com url, from your comments, is pretty tricky. They have a some bot detection for adding items to a cart. The link you specifically used doesn't seem to work no matter what, I think it is using an expired item id; I was able to use it by updating the id to 4007001 and change it to 'https'. This link however is adding an item to the cart and the site does not allow bots to add items to a cart, the site returns a 400 error with this key:value in the headers:

X-Error-Message: Bots are not allowed to add items to cart

Try adding a UserAgent to your request like this:

  myRequest.UserAgent = "Nada";

With those few changes the ZVOXAUDIO link works!

If you want keep the url as an 'https' request then just add this to your code.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12

This is required because ZVOXAUDIO does not support TLS 1.0 or earlier protocols. If the version of .NET you're using doesn't suppoert TLS 1.2, you can use SecurityProtocolType.Tls11 as ZVOXAUDIO does support TLS 1.1 still.

But since, presumably, you are attempting to have this run on as many sites as possible you probably don't want to only allow TLS 1.2, as older servers may not support it. I would set your security protocol like this:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 |
                                       SecurityProtocolType.Tls11 |
                                       SecurityProtocolType.Tls |
                                       SecurityProtocolType.Ssl3;

As a suggestion, you can set the Server Certificate Validation Callback, and the Security Protocol, outside of your loop as it is a static setting for all requests. Also if you utilize the C# using syntax, the Dispose method takes care of closing and disposing your WebResponse and StreamReader variables for you. And C# introduced 'var' back in .NET 3.0, your might want to start embracing it, that is presuming you are using the 3.0 or newer framework. If you want to see what this would look like, look below.

Make sure you have these usings:

using System;
using System.IO;
using System.Net;

Then put these two lines in the static constructor of your form, or object, I assume you are using a form right now:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;

Then your two methods would look like this:

private void button4_Click(object sender, EventArgs e)
{
  try
  {
    for (var i = 0; i < listBox2.Items.Count; i++)
    {
      var response = Code(listBox2.Items[i].ToString() + "\'");
      if (response.ToLower().Contains("mysql"))
      {
        Console.WriteLine("positive " + listBox2.Items[i].ToString());
      }
    }
  }
  catch (Exception ex)
  {
    Console.WriteLine(ex.Message);
  }
}


public static string Code(string url)
{
  var webRequest = (HttpWebRequest)WebRequest.Create(url);
  webRequest.MaximumAutomaticRedirections = 4;
  webRequest.MaximumResponseHeadersLength = 4;
  webRequest.UserAgent = "Mozilla/5.0 (Taco2) Gecko/20100101";
  webRequest.Credentials = CredentialCache.DefaultCredentials;

  webRequest.Method = "GET";

  using (var webResponse = webRequest.GetResponse())
  {
    using (var sr = new StreamReader(webResponse.GetResponseStream(), System.Text.Encoding.UTF8))
    {
      return sr.ReadToEnd();
    }
  }
}

Happy Coding! Feel free to ask any questions in the comments below.