title: Check if request comes over HTTP or HTTPS in socket listener
body: <p>I have multi threaded async socket listener. I want to check if the request comes as secure or not. But I want to check that in AcceptCallBack method not ReceiveCallBack. </p>
  
  <p>I will do that because I want my code to work for both HTTP and HTTPS. If request comes from HTTPS I will just go on with an authenticated SslStream instead of raw socket. </p>
  
  <p>Here is my code:</p>
  
  <pre><code>using System;
  using System.Net;
  using System.Net.Sockets;
  using System.Threading;
  using System.Text;
  
  namespace LearnRequestType
  {
      class StackOverFlow
      {
          private static readonly ManualResetEvent _manualResetEvent = new ManualResetEvent(false);
  
          private void StartListening()
          {
              IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 9002);
  
              if (localEndPoint != null)
              {
                  Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  
                  if (listener != null)
                  {
                      listener.Bind(localEndPoint);
                      listener.Listen(10);
  
                      Console.WriteLine("Socket listener is running...");
  
                      listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                  }
              }
          }
  
          private void AcceptCallback(IAsyncResult ar)
          {
              _manualResetEvent.Set();
  
              Socket listener = (Socket)ar.AsyncState;
  
              Socket handler = listener.EndAccept(ar);
  
              StateObject state = new StateObject();
              state.workSocket = handler;
  
              // I want to understand if request comes from HTTP or HTTPS before this line.
              handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
  
              listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
          }
  
          private void ReceiveCallback(IAsyncResult result)
          {
              StateObject state = (StateObject)result.AsyncState;
              Socket handler = state.workSocket;
  
              string clientIP = ((IPEndPoint)handler.RemoteEndPoint).Address.ToString();
  
              int numBytesReceived = handler.EndReceive(result);
  
              if (!handler.Connected)
              {
                  handler.Close();
                  return;
              }
  
              // Read incoming data...
              if (numBytesReceived &gt; 0)
              {
                  state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, numBytesReceived));
  
                  // Read incoming data line by line.
                  string[] lines = state.sb.ToString().Split('\n');
  
                  if (lines[lines.Length - 1] == "&lt;EOF&gt;")
                  {
                      // We received all data. Do something...
  
                  }
                  else
                  {
                      // We didn't receive all data. Continue reading...
                      handler.BeginReceive(state.buffer, 0, state.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
                  }
              }
          }
      }
  }
  
  public class StateObject
  {
      public Socket workSocket = null;
      public const int BufferSize = 256;
      public byte[] buffer = new byte[BufferSize];
      public StringBuilder sb = new StringBuilder();
  }
  </code></pre>
  
  <p>If I change AcceptCallBack method and StateObject Class like that: </p>
  
  <pre><code>private void AcceptCallback(IAsyncResult ar)
  {
      _manualResetEvent.Set();
  
      Socket listener = (Socket)ar.AsyncState;
  
      Socket handler = listener.EndAccept(ar);
  
      try
      {
          sslStream = new SslStream(new NetworkStream(handler, true));
  
          // try to authenticate
          sslStream.AuthenticateAsServer(_cert, false, System.Security.Authentication.SslProtocols.Tls, true);
  
          state.workStream = sslStream;
          state.workStream.ReadTimeout = 100000;
          state.workStream.WriteTimeout = 100000;
  
          if (state.workStream.IsAuthenticated)
          {
              state.workStream.BeginRead(state.buffer, 0, StateObject.BufferSize, ReceiveCallback, state);
          }
      }
      catch (IOException ex)
      {
          // ıf we get handshake failed due to an unexpected packet format, this means incoming data is not HTTPS
          // Continue with socket not sslstream
          state.workSocket = handler;
          handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
      }
  
      StateObject state = new StateObject();
      state.workStream = handler;
  
      handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
  
      listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
  }
  
  public class StateObject
  {
      public Socket workSocket = null;
      public SslStream workStream = null;
      public const int BufferSize = 1024;
      public byte[] buffer = new byte[BufferSize];
      public StringBuilder sb = new StringBuilder();
  }
  </code></pre>
  
  <p>I can decide if incoming data type is HTTP or HTTPS but if it is HTTP it will be handled by catch block every time so it will decrease application performance.</p>
  
  <p>Is there another way?</p>