Search code examples
c#.nettcpclientsslstream

How to make an HTTP Get request along with SslStream & TcpClient


In my application I am using the below code to validate the client certificate

public static async Task<string> CallApi(string url, Context context)
{
    var hostName = "mytestapp.azurewebsites.net";
    var port = 443;

    Stream keyin = Application.Context.Assets.Open("Server.pfx");
    var password = "pass123";
    using (MemoryStream memStream = new MemoryStream())
    {
        keyin.CopyTo(memStream);
        var certificates = new X509Certificate2Collection(new X509Certificate2(memStream.ToArray(), password));
        await Task.Run(() =>
        {
            // Create a TCP/IP client socket.
            // machineName is the host running the server application.
            TcpClient client = new TcpClient(hostName, port);
            Console.WriteLine("Client connected.");
            // Create an SSL stream that will close the client's stream.
            SslStream sslStream = new SslStream(
                client.GetStream(),
                false,
                ValidateServerCertificate);

            // The server name must match the name on the server certificate.
            try
            {
                sslStream.AuthenticateAsClient(hostName, certificates, SslProtocols.Tls12, true);
            }
            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;
            }
        });
    }

    return string.Empty;
}

after successful authentication, I would like to make and HTTP get request.

sslStream.AuthenticateAsClient(hostName, certificates, SslProtocols.Tls12, true);

After this statement. Say for example I need to call below http Get call

https://mytestapp.azurewebsites.net/api/GetUserProfile?userId="Sooraj"

How I can invoke this call? Or is it possible to implement the same?

Please help


Solution

  • Try something like this,

    try
                        {
                            sslStream.AuthenticateAsClient(hostName, certificates, SslProtocols.Tls12, true);
    
                            byte[] buffer = new byte[5120];
                            int bytes;
                            var pqr = string.Format("GET {0}  HTTP/1.1\r\nHost: {1}\r\n\r\n", url, "mytestapp.azurewebsites.net");
                            byte[] request = Encoding.UTF8.GetBytes(pqr);
                            sslStream.Write(request, 0, request.Length);
                            var ppp =  ReadStream(sslStream);
                            sslStream.Flush();
    
                        }
                        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;
                        }
    
    
     private static string ReadStream(Stream stream)
            {
                byte[] resultBuffer = new byte[2048];
                string value = "";
                //requestStream.BeginRead(resultBuffer, 0, resultBuffer.Length, new AsyncCallback(ReadAsyncCallback), new result() { buffer = resultBuffer, stream = requestStream, handler = callback, asyncResult = null });
                do
                {
                    try
                    {
                        int read = stream.Read(resultBuffer, 0, resultBuffer.Length);
                        value += Encoding.UTF8.GetString(resultBuffer, 0, read);
    
                        if (read < resultBuffer.Length)
                            break;
                    }
                    catch { break; }
                } while (true);
                return value;
            }
    

    It will give you the response with all set of data. and later we need to parse the required information.