Files
2026-06-04 11:42:34 +02:00

546 lines
12 KiB
C#

using System;
using System.IO;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using Mono.Security.Protocol.Tls;
namespace System.Net
{
// Token: 0x02000227 RID: 551
internal sealed class HttpConnection
{
// Token: 0x06001321 RID: 4897 RVA: 0x0003A48C File Offset: 0x0003868C
public HttpConnection(global::System.Net.Sockets.Socket sock, EndPointListener epl, bool secure, global::System.Security.Cryptography.X509Certificates.X509Certificate2 cert, AsymmetricAlgorithm key)
{
this.sock = sock;
this.epl = epl;
this.secure = secure;
this.key = key;
if (!secure)
{
this.stream = new global::System.Net.Sockets.NetworkStream(sock, false);
}
else
{
SslServerStream sslServerStream = new SslServerStream(new global::System.Net.Sockets.NetworkStream(sock, false), cert, false, false);
SslServerStream sslServerStream2 = sslServerStream;
sslServerStream2.PrivateKeyCertSelectionDelegate = (PrivateKeySelectionCallback)Delegate.Combine(sslServerStream2.PrivateKeyCertSelectionDelegate, new PrivateKeySelectionCallback(this.OnPVKSelection));
this.stream = sslServerStream;
}
this.Init();
}
// Token: 0x06001322 RID: 4898 RVA: 0x0003A514 File Offset: 0x00038714
private AsymmetricAlgorithm OnPVKSelection(X509Certificate certificate, string targetHost)
{
return this.key;
}
// Token: 0x06001323 RID: 4899 RVA: 0x0003A51C File Offset: 0x0003871C
private void Init()
{
this.context_bound = false;
this.i_stream = null;
this.o_stream = null;
this.prefix = null;
this.chunked = false;
this.ms = new MemoryStream();
this.position = 0;
this.input_state = HttpConnection.InputState.RequestLine;
this.line_state = HttpConnection.LineState.None;
this.context = new HttpListenerContext(this);
}
// Token: 0x17000632 RID: 1586
// (get) Token: 0x06001324 RID: 4900 RVA: 0x0003A578 File Offset: 0x00038778
public int ChunkedUses
{
get
{
return this.chunked_uses;
}
}
// Token: 0x17000633 RID: 1587
// (get) Token: 0x06001325 RID: 4901 RVA: 0x0003A580 File Offset: 0x00038780
public IPEndPoint LocalEndPoint
{
get
{
return (IPEndPoint)this.sock.LocalEndPoint;
}
}
// Token: 0x17000634 RID: 1588
// (get) Token: 0x06001326 RID: 4902 RVA: 0x0003A594 File Offset: 0x00038794
public IPEndPoint RemoteEndPoint
{
get
{
return (IPEndPoint)this.sock.RemoteEndPoint;
}
}
// Token: 0x17000635 RID: 1589
// (get) Token: 0x06001327 RID: 4903 RVA: 0x0003A5A8 File Offset: 0x000387A8
public bool IsSecure
{
get
{
return this.secure;
}
}
// Token: 0x17000636 RID: 1590
// (get) Token: 0x06001328 RID: 4904 RVA: 0x0003A5B0 File Offset: 0x000387B0
// (set) Token: 0x06001329 RID: 4905 RVA: 0x0003A5B8 File Offset: 0x000387B8
public ListenerPrefix Prefix
{
get
{
return this.prefix;
}
set
{
this.prefix = value;
}
}
// Token: 0x0600132A RID: 4906 RVA: 0x0003A5C4 File Offset: 0x000387C4
public void BeginReadRequest()
{
if (this.buffer == null)
{
this.buffer = new byte[8192];
}
try
{
this.stream.BeginRead(this.buffer, 0, 8192, new AsyncCallback(this.OnRead), this);
}
catch
{
this.CloseSocket();
}
}
// Token: 0x0600132B RID: 4907 RVA: 0x0003A640 File Offset: 0x00038840
public RequestStream GetRequestStream(bool chunked, long contentlength)
{
if (this.i_stream == null)
{
byte[] array = this.ms.GetBuffer();
int num = (int)this.ms.Length;
this.ms = null;
if (chunked)
{
this.chunked = true;
this.context.Response.SendChunked = true;
this.i_stream = new ChunkedInputStream(this.context, this.stream, array, this.position, num - this.position);
}
else
{
this.i_stream = new RequestStream(this.stream, array, this.position, num - this.position, contentlength);
}
}
return this.i_stream;
}
// Token: 0x0600132C RID: 4908 RVA: 0x0003A6E8 File Offset: 0x000388E8
public ResponseStream GetResponseStream()
{
if (this.o_stream == null)
{
HttpListener listener = this.context.Listener;
bool flag = listener == null || listener.IgnoreWriteExceptions;
this.o_stream = new ResponseStream(this.stream, this.context.Response, flag);
}
return this.o_stream;
}
// Token: 0x0600132D RID: 4909 RVA: 0x0003A744 File Offset: 0x00038944
private void OnRead(IAsyncResult ares)
{
HttpConnection httpConnection = (HttpConnection)ares.AsyncState;
int num = -1;
try
{
num = this.stream.EndRead(ares);
this.ms.Write(this.buffer, 0, num);
if (this.ms.Length > 32768L)
{
this.SendError("Bad request", 400);
this.Close(true);
return;
}
}
catch
{
if (this.ms != null && this.ms.Length > 0L)
{
this.SendError();
}
if (this.sock != null)
{
this.CloseSocket();
}
return;
}
if (num == 0)
{
this.CloseSocket();
return;
}
if (this.ProcessInput(this.ms))
{
if (!this.context.HaveError)
{
this.context.Request.FinishInitialization();
}
if (this.context.HaveError)
{
this.SendError();
this.Close(true);
return;
}
if (!this.epl.BindContext(this.context))
{
this.SendError("Invalid host", 400);
this.Close(true);
}
this.context_bound = true;
return;
}
else
{
this.stream.BeginRead(this.buffer, 0, 8192, new AsyncCallback(this.OnRead), httpConnection);
}
}
// Token: 0x0600132E RID: 4910 RVA: 0x0003A8C8 File Offset: 0x00038AC8
private bool ProcessInput(MemoryStream ms)
{
byte[] array = ms.GetBuffer();
int num = (int)ms.Length;
int num2 = 0;
string text;
try
{
text = this.ReadLine(array, this.position, num - this.position, ref num2);
this.position += num2;
}
catch (Exception ex)
{
this.context.ErrorMessage = "Bad request";
this.context.ErrorStatus = 400;
return true;
}
while (text != null)
{
if (text == string.Empty)
{
if (this.input_state != HttpConnection.InputState.RequestLine)
{
this.current_line = null;
ms = null;
return true;
}
}
else
{
if (this.input_state == HttpConnection.InputState.RequestLine)
{
this.context.Request.SetRequestLine(text);
this.input_state = HttpConnection.InputState.Headers;
}
else
{
try
{
this.context.Request.AddHeader(text);
}
catch (Exception ex2)
{
this.context.ErrorMessage = ex2.Message;
this.context.ErrorStatus = 400;
return true;
}
}
if (this.context.HaveError)
{
return true;
}
if (this.position >= num)
{
break;
}
try
{
text = this.ReadLine(array, this.position, num - this.position, ref num2);
this.position += num2;
}
catch (Exception ex3)
{
this.context.ErrorMessage = "Bad request";
this.context.ErrorStatus = 400;
return true;
}
}
if (text != null)
{
continue;
}
IL_194:
if (num2 == num)
{
ms.SetLength(0L);
this.position = 0;
}
return false;
}
goto IL_194;
}
// Token: 0x0600132F RID: 4911 RVA: 0x0003AAD0 File Offset: 0x00038CD0
private string ReadLine(byte[] buffer, int offset, int len, ref int used)
{
if (this.current_line == null)
{
this.current_line = new StringBuilder();
}
int num = offset + len;
used = 0;
int num2 = offset;
while (num2 < num && this.line_state != HttpConnection.LineState.LF)
{
used++;
byte b = buffer[num2];
if (b == 13)
{
this.line_state = HttpConnection.LineState.CR;
}
else if (b == 10)
{
this.line_state = HttpConnection.LineState.LF;
}
else
{
this.current_line.Append((char)b);
}
num2++;
}
string text = null;
if (this.line_state == HttpConnection.LineState.LF)
{
this.line_state = HttpConnection.LineState.None;
text = this.current_line.ToString();
this.current_line.Length = 0;
}
return text;
}
// Token: 0x06001330 RID: 4912 RVA: 0x0003AB8C File Offset: 0x00038D8C
public void SendError(string msg, int status)
{
try
{
HttpListenerResponse response = this.context.Response;
response.StatusCode = status;
response.ContentType = "text/html";
string statusDescription = HttpListenerResponse.GetStatusDescription(status);
string text;
if (msg != null)
{
text = string.Format("<h1>{0} ({1})</h1>", statusDescription, msg);
}
else
{
text = string.Format("<h1>{0}</h1>", statusDescription);
}
byte[] bytes = this.context.Response.ContentEncoding.GetBytes(text);
response.Close(bytes, false);
}
catch
{
}
}
// Token: 0x06001331 RID: 4913 RVA: 0x0003AC28 File Offset: 0x00038E28
public void SendError()
{
this.SendError(this.context.ErrorMessage, this.context.ErrorStatus);
}
// Token: 0x06001332 RID: 4914 RVA: 0x0003AC48 File Offset: 0x00038E48
private void Unbind()
{
if (this.context_bound)
{
this.epl.UnbindContext(this.context);
this.context_bound = false;
}
}
// Token: 0x06001333 RID: 4915 RVA: 0x0003AC70 File Offset: 0x00038E70
public void Close()
{
this.Close(false);
}
// Token: 0x06001334 RID: 4916 RVA: 0x0003AC7C File Offset: 0x00038E7C
private void CloseSocket()
{
if (this.sock == null)
{
return;
}
try
{
this.sock.Close();
}
catch
{
}
finally
{
this.sock = null;
}
}
// Token: 0x06001335 RID: 4917 RVA: 0x0003ACE8 File Offset: 0x00038EE8
internal void Close(bool force_close)
{
if (this.sock != null)
{
Stream responseStream = this.GetResponseStream();
responseStream.Close();
this.o_stream = null;
}
if (this.sock == null)
{
return;
}
force_close |= this.context.Request.Headers["connection"] == "close";
if (!force_close)
{
int statusCode = this.context.Response.StatusCode;
bool flag = statusCode == 400 || statusCode == 408 || statusCode == 411 || statusCode == 413 || statusCode == 414 || statusCode == 500 || statusCode == 503;
force_close |= this.context.Request.ProtocolVersion <= HttpVersion.Version10;
}
if (force_close || !this.context.Request.FlushInput())
{
global::System.Net.Sockets.Socket socket = this.sock;
this.sock = null;
try
{
if (socket != null)
{
socket.Shutdown(global::System.Net.Sockets.SocketShutdown.Both);
}
}
catch
{
}
finally
{
if (socket != null)
{
socket.Close();
}
}
this.Unbind();
return;
}
if (this.chunked && !this.context.Response.ForceCloseChunked)
{
this.chunked_uses++;
this.Unbind();
this.Init();
this.BeginReadRequest();
return;
}
this.Unbind();
this.Init();
this.BeginReadRequest();
}
// Token: 0x0400104B RID: 4171
private const int BufferSize = 8192;
// Token: 0x0400104C RID: 4172
private global::System.Net.Sockets.Socket sock;
// Token: 0x0400104D RID: 4173
private Stream stream;
// Token: 0x0400104E RID: 4174
private EndPointListener epl;
// Token: 0x0400104F RID: 4175
private MemoryStream ms;
// Token: 0x04001050 RID: 4176
private byte[] buffer;
// Token: 0x04001051 RID: 4177
private HttpListenerContext context;
// Token: 0x04001052 RID: 4178
private StringBuilder current_line;
// Token: 0x04001053 RID: 4179
private ListenerPrefix prefix;
// Token: 0x04001054 RID: 4180
private RequestStream i_stream;
// Token: 0x04001055 RID: 4181
private ResponseStream o_stream;
// Token: 0x04001056 RID: 4182
private bool chunked;
// Token: 0x04001057 RID: 4183
private int chunked_uses;
// Token: 0x04001058 RID: 4184
private bool context_bound;
// Token: 0x04001059 RID: 4185
private bool secure;
// Token: 0x0400105A RID: 4186
private AsymmetricAlgorithm key;
// Token: 0x0400105B RID: 4187
private HttpConnection.InputState input_state;
// Token: 0x0400105C RID: 4188
private HttpConnection.LineState line_state;
// Token: 0x0400105D RID: 4189
private int position;
// Token: 0x02000228 RID: 552
private enum InputState
{
// Token: 0x0400105F RID: 4191
RequestLine,
// Token: 0x04001060 RID: 4192
Headers
}
// Token: 0x02000229 RID: 553
private enum LineState
{
// Token: 0x04001062 RID: 4194
None,
// Token: 0x04001063 RID: 4195
CR,
// Token: 0x04001064 RID: 4196
LF
}
}
}