1

I have an old program that used to make calls to HTTP streams (Icecast,shoutcast) and analyze them to get the MetaData from the stream. The program worked well when streams were all set under HTTP only. I'm trying to add the ability to call HTTPS streams. This program uses the NetworkStream object that doesn't work with SSL. Using SslStream works the problem out, but, since this program has a lot of dependencies on the NetworkStream object, I was wondering if there is a hack/patch to copy an SslStream object into a NetworkStream object to keep using the NetworkStream object without replacing it with SSLStream.

This this is my code for the Http stream:

 public Playable HttpAnalyzer()
    {
        string protocol;
        string host;
        int port;
        string target;
        string errMsg;

        if (!Utils.ParseHttpURL(url, out protocol, out host, out port, out target, out errMsg))
        {
            traceInfo.AddLine(TraceInfo.EntryKind.Alert, errMsg);
            return null;
        }

        string[] headers = new string[] 
        {
            String.Format("GET {0} HTTP/1.0", target), 
            (port != 80 ? String.Format("Host: {0}:{1}", host, port) : String.Format("Host: {0}", host)),
            "User-Agent: NSPlayer/8.0.0.4477",
            "Icy-Metadata: 1",
            "Connection: close"
        };

        try
        {
            using (TcpClient client = new TcpClient())
            {
                client.SendTimeout = 5000;
                client.ReceiveTimeout = 5000;
                client.Connect(host, port);

                using (NetworkStream ns = client.GetStream())
                {

                    StringBuilder sb = new StringBuilder();
                    foreach (string requestHeader in headers)
                    {
                        sb.Append(requestHeader);
                        sb.Append("\r\n");
                    }
                    sb.Append("\r\n");

                    byte[] headerBytes = Encoding.ASCII.GetBytes(sb.ToString());
                    ns.Write(headerBytes, 0, headerBytes.Length);
                    List<string> responseHeaders = new List<string>();

                    string responseHeader;
                    while (Utils.ReadLine(ns, Encoding.ASCII, out responseHeader) && responseHeader.Length > 0)
                    {
                        responseHeaders.Add(responseHeader);
                    }

                    if (responseHeaders.Count == 0)
                    {
                        traceInfo.AddLine(TraceInfo.EntryKind.Alert, "Response is empty");
                        try
                        {
                            client.GetStream().Close();
                            client.Close();
                        }
                        catch
                        {
                        }
                        //client.Client.Disconnect(false);
                        return null;
                    }

                    Playable pl = HandleResponse(responseHeaders.ToArray(), ns);
                    client.GetStream().Close();
                    client.Close();
                    return pl;
                }
            }
        }
        catch (Exception e)
        {
            traceInfo.AddLine(TraceInfo.EntryKind.Alert, String.Format("Exception: {0}", e.Message));
        }

        return null;
    }

Note that the NetworkStream ReadByte function is in a different class:

 public static bool ReadLine(NetworkStream ns, Encoding encoding, out string line)
    {
        List<byte> bytes = new List<byte>();

        bool readSomething = false;

        try
        {
            int b;
            while ((b = ns.ReadByte()) != -1)
            {
                readSomething = true;

                if (b != 13 && b != 10)
                {
                    bytes.Add((byte)b);
                }

                if (b == 10)
                {
                    break;
                }
            }
        }
        catch (Exception ex)
        {
        }

        line = encoding.GetString(bytes.ToArray());

        return readSomething;
    }

How would I need to modify it to make the SSL call, and force the result into NetworkStream somehow?

Basilf
  • 401
  • 5
  • 17
  • [SslStream](https://learn.microsoft.com/fr-fr/dotnet/api/system.net.security.sslstream) – Kalten Oct 27 '19 at 11:19
  • @Kalten, what part of this doc answers my specific question? – Basilf Oct 27 '19 at 13:27
  • 1
    None. I don't know any hacky way to do what you want. But I suggest you to replace in your dependency (if possible) every usage of NetworkStream by the base class Stream. You should not need to manage Networkstream directly – Kalten Oct 27 '19 at 13:56
  • @Kalten this could work actually.... :) – Basilf Oct 27 '19 at 14:38
  • Look at [here](https://stackoverflow.com/questions/15227492/how-to-allow-a-server-to-accept-both-ssl-and-plain-text-insecure-connections), similar to what you asked. – cdev Oct 27 '19 at 15:00

0 Answers0