Как заставить NetworkStream работать с SSL? - PullRequest
1 голос
/ 27 октября 2019

У меня есть старая программа, которая использовала для вызовов HTTP-потоков (Icecast, shoutcast) и анализировать их, чтобы получить метаданные из потока. Программа работала хорошо, когда все потоки были настроены только по HTTP. Я пытаюсь добавить возможность вызова потоков HTTPS. Эта программа использует объект NetworkStream, который не работает с SSL. Использование SslStream решает эту проблему, но, поскольку эта программа имеет много зависимостей от объекта NetworkStream, мне было интересно, есть ли хак / патч для копирования объекта SslStream в объект NetworkStream, чтобы продолжать использовать объект NetworkStream, не заменяя егос SSLStream.

Это мой код для потока Http:

 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;
    }

Обратите внимание, что функция NetworkStream ReadByte находится в другом классе:

 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;
    }

Как мне нужноизменить его так, чтобы он вызывал SSL, и каким-то образом принудительно вызвать результат в NetworkStream?

...