|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Specialized;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Net.Security;
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
using System.Security.Authentication;
|
|
|
|
|
|
|
|
|
|
using UMC.Net;
|
|
|
|
|
|
|
|
|
|
namespace UMC.ITME
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
public class HttpMimeSocket : HttpMime
|
|
|
|
|
{
|
|
|
|
|
public override string Scheme => "http";
|
|
|
|
|
|
|
|
|
|
public HttpMimeSocket(Socket socket, String ip)
|
|
|
|
|
{
|
|
|
|
|
this._socket = socket;
|
|
|
|
|
this.ActiveTime = UMC.Data.Utility.TimeSpan();
|
|
|
|
|
|
|
|
|
|
this.pid = socket.GetHashCode();
|
|
|
|
|
|
|
|
|
|
this._Host = "127.0.0.1";
|
|
|
|
|
|
|
|
|
|
this._remoteIpAddress = ip;
|
|
|
|
|
|
|
|
|
|
HttpMimeServier.httpMimes.TryAdd(pid, this);
|
|
|
|
|
SocketAsyncEventArgs eventArgs = new SocketAsyncEventArgs();
|
|
|
|
|
|
|
|
|
|
eventArgs.SetBuffer(_data);
|
|
|
|
|
eventArgs.Completed += Http;
|
|
|
|
|
if (!this._socket.ReceiveAsync(eventArgs))
|
|
|
|
|
{
|
|
|
|
|
Receive(eventArgs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Socket _socket;
|
|
|
|
|
int pid = 0;
|
|
|
|
|
public override int Id => pid;
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
this.Dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// UMC.Net.MimeRequest request;
|
|
|
|
|
private void Http(object sender, SocketAsyncEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
switch (e.LastOperation)
|
|
|
|
|
{
|
|
|
|
|
case SocketAsyncOperation.Receive:
|
|
|
|
|
Receive(e);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bool IsHeader = true;
|
|
|
|
|
private void Receive(SocketAsyncEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (ProcessReceive(e))
|
|
|
|
|
{
|
|
|
|
|
while (this.isDispose == false && !_socket.ReceiveAsync(e))
|
|
|
|
|
{
|
|
|
|
|
if (!ProcessReceive(e))
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private bool ProcessReceive(SocketAsyncEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (e.SocketError == SocketError.Success)
|
|
|
|
|
{
|
|
|
|
|
if (e.BytesTransferred > 0)
|
|
|
|
|
{
|
|
|
|
|
this.ActiveTime = UMC.Data.Utility.TimeSpan();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (this.Request == null)
|
|
|
|
|
{
|
|
|
|
|
if (IsHeader)
|
|
|
|
|
{
|
|
|
|
|
if (this._data[0] == 0x1)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Subscribe(this._data, e.Offset + 1, e.BytesTransferred - 1);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Utility.Error("Subscribe", ex.ToString());
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
this.Dispose();
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
IsHeader = true;
|
|
|
|
|
}
|
|
|
|
|
this.Request = new HttpMimeRequest(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var req = this.Request;
|
|
|
|
|
|
|
|
|
|
req.Receive(this._data, e.Offset, e.BytesTransferred);
|
|
|
|
|
|
|
|
|
|
if (req.IsHttpFormatError)
|
|
|
|
|
{
|
|
|
|
|
this.Dispose();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else if (this.isDispose == false)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
this.OutText(500, ex.ToString());
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.Dispose();
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Subscribe(byte[] header, int offset, int size)
|
|
|
|
|
{
|
|
|
|
|
var headers = new NameValueCollection();
|
|
|
|
|
var ps = System.Text.Encoding.UTF8.GetString(header, offset, size).Split("\r\n", StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
foreach (var s in ps)
|
|
|
|
|
{
|
|
|
|
|
var vi = s.IndexOf(':');
|
|
|
|
|
if (vi > 0 && vi + 2 < s.Length)
|
|
|
|
|
{
|
|
|
|
|
var key = s.Substring(0, vi);
|
|
|
|
|
var value = s.Substring(vi + 2);
|
|
|
|
|
headers.Add(key, value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int length = 0;
|
|
|
|
|
var _subscribe = UMC.Net.NetSubscribe.Subscribe(headers, this._remoteIpAddress, HttpMimeServier.Server, _socket, UMC.Data.WebResource.Instance().Provider["appSecret"]);
|
|
|
|
|
if (_subscribe != null)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
length += "Server: ITME\r\n\r\n".WriteBytes(header, length);
|
|
|
|
|
_socket.Send(header, 0, length, SocketFlags.None);
|
|
|
|
|
|
|
|
|
|
_socket = null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
length += "Server: ITME\r\n\r\n".WriteBytes(header, length);
|
|
|
|
|
length += text.WriteBytes(header, length);
|
|
|
|
|
|
|
|
|
|
_socket.Send(header, 0, length, SocketFlags.None);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bool isDispose = false;
|
|
|
|
|
public override void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (isDispose == false)
|
|
|
|
|
{
|
|
|
|
|
if (this._data != null)
|
|
|
|
|
{
|
|
|
|
|
System.Buffers.ArrayPool<byte>.Shared.Return(this._data);
|
|
|
|
|
_data = null;
|
|
|
|
|
}
|
|
|
|
|
isDispose = true;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (this.Request is IDisposable)
|
|
|
|
|
{
|
|
|
|
|
((IDisposable)this.Request).Dispose();
|
|
|
|
|
}
|
|
|
|
|
_socket?.Shutdown(SocketShutdown.Both);
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
_socket?.Close();
|
|
|
|
|
}
|
|
|
|
|
HttpMimeServier.httpMimes.TryRemove(pid, out var _);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
byte[] _data = System.Buffers.ArrayPool<byte>.Shared.Rent(0x600);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|