Ho listener di socket asincratico multi-thread. Voglio verificare se la richiesta è sicura o meno. Ma voglio verificare che nel metodo AcceptCallBack non ReceiveCallBack.Verifica se la richiesta arriva tramite HTTP o HTTPS nell'ascoltatore di socket
Lo farò perché voglio che il mio codice funzioni sia per HTTP che per HTTPS. Se la richiesta proviene da HTTPS, procederò con un SslStream autenticato invece che con socket non elaborato.
Ecco il mio codice:
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 > 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] == "<EOF>")
{
// 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();
}
Se cambio AcceptCallBack metodo e StateObject Classe così:
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();
}
posso decidere se il tipo di dati in ingresso è HTTP o HTTPS, ma se si tratta di HTTP verrà gestito da catch catch ogni volta, quindi diminuirà le prestazioni dell'applicazione.
C'è un altro modo?
Grazie per la risposta. In realtà posso verificare se è HTTP o HTTPS facendo così. Controlla la mia domanda modificata. Ma qui il problema è provare a catturare i blocchi. –
@OrkunBekar Aggiunta di informazioni su come avere una buona intuizione se si tratta di HTTP o meno. –
Come posso vedere la versione del protocollo? È memorizzato all'interno di un oggetto nel metodo AcceptCallBack? Dove avrò questi due valori uint8? –