mirror of https://gitee.com/apiumc/Gateway.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
4.7 KiB
C#
157 lines
4.7 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.IO.Pipes;
|
|
using System.Net;
|
|
using System.Net.Security;
|
|
using System.Net.Sockets;
|
|
using System.Security.Authentication;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Threading.Tasks;
|
|
using UMC.Net;
|
|
|
|
namespace UMC.Host
|
|
{
|
|
|
|
class HttpBridgeMime : HttpMime
|
|
{
|
|
HttpBridgeClient client;
|
|
public HttpBridgeMime(int pid, HttpBridgeClient client)
|
|
{
|
|
this.client = client;
|
|
this.pid = pid;
|
|
}
|
|
int pid;
|
|
public override string Host => "127.0.0.1";
|
|
|
|
public override string RemoteIpAddress => "127.0.0.1";
|
|
|
|
public override void Dispose()
|
|
{
|
|
if (_webSocket != null)
|
|
{
|
|
_webSocket.Close();
|
|
_webSocket.Dispose();
|
|
}
|
|
client.Remove(this.pid);
|
|
}
|
|
public void WebSocket(byte[] buffer, int offset, int count)
|
|
{
|
|
try
|
|
{
|
|
mimeStream?.Write(buffer, offset, count);
|
|
_webSocket?.Write(buffer, offset, count);
|
|
}
|
|
catch
|
|
{
|
|
client.Write(this.pid, new byte[0], 0, 0);
|
|
this.Dispose();
|
|
}
|
|
}
|
|
public override void Subscribe(HttpMimeRequest webRequest)
|
|
{
|
|
this.OutText(500, "穿透不支持UMC数据订阅协议");
|
|
}
|
|
|
|
protected override void WebSocket(NetContext context)
|
|
{
|
|
if (context.Tag is HttpWebRequest)
|
|
{
|
|
var webr = context.Tag as HttpWebRequest;
|
|
this.WebSocket(webr);
|
|
}
|
|
else
|
|
{
|
|
mimeStream = new HttpMimeStream(this);
|
|
HttpWebSocket.AcceptWebSocketAsyncCore(context, mimeStream);// new HttpMimeStream(this));
|
|
}
|
|
}
|
|
HttpMimeStream mimeStream;
|
|
async void WebSocket(HttpWebRequest webRequest)
|
|
{
|
|
try
|
|
{
|
|
var url = webRequest.RequestUri;
|
|
if (webRequest.CookieContainer != null)
|
|
{
|
|
String cookie;
|
|
if (webRequest.CookieContainer is Net.NetCookieContainer)
|
|
{
|
|
cookie = ((Net.NetCookieContainer)webRequest.CookieContainer).GetCookieHeader(url);
|
|
}
|
|
else
|
|
{
|
|
cookie = webRequest.CookieContainer.GetCookieHeader(url);
|
|
}
|
|
if (String.IsNullOrEmpty(cookie) == false)
|
|
{
|
|
webRequest.Headers[HttpRequestHeader.Cookie] = cookie;
|
|
}
|
|
}
|
|
if (String.IsNullOrEmpty(webRequest.Headers[HttpRequestHeader.Host]))
|
|
{
|
|
webRequest.Headers[HttpRequestHeader.Host] = webRequest.Host;
|
|
}
|
|
webRequest.Headers["Connection"] = "Upgrade";
|
|
|
|
|
|
|
|
var client = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
|
|
|
await client.ConnectAsync(url.Host, url.Port);
|
|
|
|
|
|
if (url.Scheme == "https")
|
|
{
|
|
SslStream ssl = new SslStream(new NetworkStream(client, true), false, (sender, certificate, chain, sslPolicyErrors) => true);
|
|
|
|
await ssl.AuthenticateAsClientAsync(url.Host, new X509CertificateCollection(), SslProtocols.None, false);
|
|
_webSocket = ssl;
|
|
}
|
|
else
|
|
{
|
|
_webSocket = new NetworkStream(client, true);
|
|
|
|
}
|
|
var buffer = new byte[0x600];
|
|
await _webSocket.WriteAsync(buffer, 0, NetHttpResponse.Header(webRequest, buffer));
|
|
WebSocketRead(buffer);
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
this.OutText(500, ex.ToString());
|
|
this.Dispose();
|
|
}
|
|
}
|
|
Stream _webSocket;
|
|
async void WebSocketRead(byte[] buffer)
|
|
{
|
|
int size = 0;
|
|
try
|
|
{
|
|
size = await _webSocket.ReadAsync(buffer, 0, buffer.Length);
|
|
client.Write(this.pid, buffer, 0, size);
|
|
WebSocketRead(buffer);
|
|
}
|
|
catch
|
|
{
|
|
client.Write(this.pid, Array.Empty<byte>(), 0, 0);
|
|
this.Dispose();
|
|
}
|
|
}
|
|
public override void OutputFinish()
|
|
{
|
|
|
|
}
|
|
public override void Write(byte[] buffer, int offset, int count)
|
|
{
|
|
if (count > 0)
|
|
{
|
|
|
|
client.Write(this.pid, buffer, offset, count);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|