How to send valid HTTPS requests to a web service via SslStream and TcpClient
<p>I'm essentially attempting to setup a HTTPS client I can use for automated testing APIs and other web services I'm developing. I'm familiar with using sockets, but not so much with using SSL/TLS in code. I've started by attempting to setup a client that sends an HTTP request to google.com with the following header: <code>GET / HTTP/1.1</code></p>

<p>The idea is to receive a basic HTTP response from Google, via an encrypted connection of course. This is really easy when using unencrypted HTTP - I can even telnet into google over port 80 and enter <code>GET / HTTP/1.1</code> and I receive a nice HTTP response header and HTML payload. Implementing the C/C# code for making unencrypted HTTP requests is also not very difficult.  It's SSL that is giving me a difficult time.</p>

<p>Using the code below (full sample found at <a href="https://msdn.microsoft.com/en-us/library/system.net.security.sslstream.aspx?cs-save-lang=1&amp;cs-lang=csharp#code-snippet-3" rel="nofollow noreferrer">https://msdn.microsoft.com/en-us/library/system.net.security.sslstream.aspx?cs-save-lang=1&amp;cs-lang=csharp#code-snippet-3</a>), which is an almost identical implementation to what is provided by MSDN for reference, I can successfully connect to <code>google.com</code> and validate the server certificate:</p>

<pre><code>        // Create a TCP/IP client socket.
        // machineName is the host running the server application.
        TcpClient client = new TcpClient(machineName, 443);
        Console.WriteLine("Client connected.");
        // Create an SSL stream that will close the client's stream.
        SslStream sslStream = new SslStream(
            client.GetStream(),
            false,
            new RemoteCertificateValidationCallback(ValidateServerCertificate),
            null
            );
        // The server name must match the name on the server certificate.
        try
        {
            sslStream.AuthenticateAsClient(serverName);
        }
        catch (AuthenticationException e)
        {
            Console.WriteLine("Exception: {0}", e.Message);
            if (e.InnerException != null)
            {
                Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
            }
            Console.WriteLine("Authentication failed - closing the connection.");
            client.Close();
            return;
        }
</code></pre>

<p>The issue is when the following code executes, the ReadMessage(sslStream) instruction hangs, as in I don't receive a response for a very long time, and when the response finally comes in it is an empty string:</p>

<pre><code>        // Encode a test message into a byte array.
        // Signal the end of the message using the "&lt;EOF&gt;".
        byte[] messsage = Encoding.UTF8.GetBytes("GET / HTTP/1.1&lt;EOF&gt;");
        // Send hello message to the server. 
        sslStream.Write(messsage);
        sslStream.Flush();
        // Read message from the server.
        string serverMessage = ReadMessage(sslStream);
        Console.WriteLine("Server says: {0}", serverMessage);
</code></pre>

<p>Therefore, I'm unable to receive the HTTP response I was looking for (or anything at all) when I make this request over a secure socket connection. The idea in the long run is to start using this client to send customized HTTP requests to my own APIs and web services, but I certainly cannot do that if I cannot even get a generic response from google.com.  Does anyone have an idea why the ReadMessage() function is timing out or otherwise providing no response? The sample code seems very straightforward so I'm having a hard time understanding what I'm doing wrong.</p>