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.
Gateway/Mime/HttpMimeSocket.cs

229 lines
7.5 KiB
C#

2 years ago
using System;
1 year ago
using System.Collections.Specialized;
2 years ago
using System.IO;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
2 years ago
using UMC.Net;
10 months ago
namespace UMC.ITME
2 years ago
{
1 year ago
1 year ago
public class HttpMimeSocket : HttpMime
{
public override string Scheme => "http";
2 years ago
1 year ago
public HttpMimeSocket(Socket socket, String ip)
2 years ago
{
this._socket = socket;
2 years ago
this.ActiveTime = UMC.Data.Utility.TimeSpan();
this.pid = socket.GetHashCode();
2 years ago
1 year ago
this._Host = "127.0.0.1";
2 years ago
this._remoteIpAddress = ip;
HttpMimeServier.httpMimes.TryAdd(pid, this);
1 year ago
SocketAsyncEventArgs eventArgs = new SocketAsyncEventArgs();
eventArgs.SetBuffer(_data);
eventArgs.Completed += Http;
if (!this._socket.ReceiveAsync(eventArgs))
{
10 months ago
Receive(eventArgs);
}
2 years ago
}
Socket _socket;
2 years ago
int pid = 0;
1 year ago
public override int Id => pid;
2 years ago
String _remoteIpAddress, _Host;
public override String Host => _Host;
public override String RemoteIpAddress => _remoteIpAddress;
public override void Write(byte[] buffer, int offset, int count)
{
if (isDispose == false)
{
try
{
_socket.Send(buffer, offset, count, SocketFlags.None);
2 years ago
}
catch
{
this.Dispose();
}
}
}
// UMC.Net.MimeRequest request;
1 year ago
private void Http(object sender, SocketAsyncEventArgs e)
{
switch (e.LastOperation)
{
case SocketAsyncOperation.Receive:
10 months ago
Receive(e);
1 year ago
break;
}
}
1 year ago
bool IsHeader = true;
10 months ago
private void Receive(SocketAsyncEventArgs e)
{
if (ProcessReceive(e))
{
while (this.isDispose == false && !_socket.ReceiveAsync(e))
{
if (!ProcessReceive(e))
{
break;
}
}
}
}
private bool ProcessReceive(SocketAsyncEventArgs e)
1 year ago
{
if (e.SocketError == SocketError.Success)
1 year ago
{
if (e.BytesTransferred > 0)
1 year ago
{
this.ActiveTime = UMC.Data.Utility.TimeSpan();
try
1 year ago
{
if (this.Request == null)
1 year ago
{
if (IsHeader)
1 year ago
{
if (this._data[0] == 0x1)
1 year ago
{
try
{
Subscribe(this._data, e.Offset + 1, e.BytesTransferred - 1);
// _socket = null;
}
10 months ago
catch (Exception ex)
{
10 months ago
Utility.Error("Subscribe", ex.ToString());
}
finally
{
this.Dispose();
}
10 months ago
return false;
1 year ago
}
10 months ago
IsHeader = true;
1 year ago
}
this.Request = new HttpMimeRequest(this);
1 year ago
}
var req = this.Request;
// req.Receive(this._data, 0, size);
req.Receive(this._data, e.Offset, e.BytesTransferred);
if (req.IsHttpFormatError)
{
this.Dispose();
10 months ago
return false;
}
10 months ago
else if (this.isDispose == false)
{
10 months ago
return true;
// ProcessReceive(e);
}
}
catch (Exception ex)
{
this.OutText(500, ex.ToString());
1 year ago
10 months ago
return false;
}
1 year ago
}
10 months ago
return false;
1 year ago
}
else
{
this.Dispose();
10 months ago
return false;
1 year ago
}
}
2 years ago
1 year ago
void Subscribe(byte[] header, int offset, int size)
2 years ago
{
1 year ago
var headers = new NameValueCollection();
10 months ago
var ps = System.Text.Encoding.UTF8.GetString(header, offset, size).Split("\r\n", StringSplitOptions.RemoveEmptyEntries);
1 year ago
foreach (var s in ps)
2 years ago
{
10 months ago
1 year ago
var vi = s.IndexOf(':');
var key = s.Substring(0, vi);
var value = s.Substring(vi + 2);
headers.Add(key, value);
}
2 years ago
1 year ago
int length = 0;
var _subscribe = UMC.Net.NetSubscribe.Subscribe(headers, this._remoteIpAddress, HttpMimeServier.Server, _socket, UMC.Data.WebResource.Instance().Provider["appSecret"]);
if (_subscribe != null)
{
2 years ago
1 year ago
length += $"HTTP/1.1 101 {HttpStatusDescription.Get(101)}\r\n".WriteBytes(header, length);
length += "Connection: upgrade\r\n".WriteBytes(header, length);
length += "Upgrade: websocket\r\n".WriteBytes(header, length);
length += $"UMC-Publisher-Key: {HttpMimeServier.Server}\r\n".WriteBytes(header, length);
10 months ago
length += "Server: ITME\r\n\r\n".WriteBytes(header, length);
1 year ago
_socket.Send(header, 0, length, SocketFlags.None);
10 months ago
1 year ago
_socket = null;
2 years ago
}
else
{
1 year ago
var text = "数据订阅连接验证不通过";
length += $"HTTP/1.1 401 {HttpStatusDescription.Get(401)}\r\n".WriteBytes(header, length);
length += $"Content-Type: text/plain; charset=utf-8\r\n".WriteBytes(header, length);
length += $"Content-Length: {System.Text.Encoding.UTF8.GetByteCount(text)}\r\n".WriteBytes(header, length);
length += "Connection: close\r\n".WriteBytes(header, length);
10 months ago
length += "Server: ITME\r\n\r\n".WriteBytes(header, length);
1 year ago
length += text.WriteBytes(header, length);
_socket.Send(header, 0, length, SocketFlags.None);
2 years ago
}
}
bool isDispose = false;
public override void Dispose()
{
if (isDispose == false)
{
if (this._data != null)
{
System.Buffers.ArrayPool<byte>.Shared.Return(this._data);
_data = null;
}
2 years ago
isDispose = true;
try
{
if (this.Request is IDisposable)
{
((IDisposable)this.Request).Dispose();
}
_socket?.Shutdown(SocketShutdown.Both);
2 years ago
}
catch
{
}
_socket?.Close();
2 years ago
}
HttpMimeServier.httpMimes.TryRemove(pid, out var _);
}
1 year ago
byte[] _data = System.Buffers.ArrayPool<byte>.Shared.Rent(0x600);
2 years ago
}
}