CarotDav_decompile/Rei.Net.HttpServer/MyHttpServerConnection.cs

1665 lines
52 KiB
C#
Raw Normal View History

// Decompiled with JetBrains decompiler
// Type: Rei.Net.HttpServer.MyHttpServerConnection
// Assembly: Rei.Net.HttpServer, Version=1.13.2.9297, Culture=neutral, PublicKeyToken=null
// MVID: 6174F8E9-E7BA-46AD-8F2E-196645884F28
// Assembly location: F:\Eigene Dateien\Dropbox\portable Collection\Progs\CarotDAV\Rei.Net.HttpServer.dll
using Microsoft.VisualBasic.CompilerServices;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
namespace Rei.Net.HttpServer
{
[DebuggerDisplay("{toString}")]
public class MyHttpServerConnection : IDisposable
{
private static string[] HeaderOrder = new string[46]
{
"Cache-Control",
"Connection",
"Date",
"Pragma",
"Trailer",
"Transfer-Encoding",
"Upgrade",
"Via",
"Warning",
"Accept-Charset",
"Accept-Encoding",
"Accept-Language",
"Authorization",
"Expect",
"From",
"Host",
"If-Match",
"If-Modified-Since",
"If-None-Match",
"If-Range",
"If-Unmodified-Since",
"Max-Forwards",
"Proxy-Authorization",
"Range",
"Referer",
"TE",
"User-Agent",
"Accept-Ranges",
"Age",
"ETag",
"Location",
"Proxy-Authenticate",
"Retry-After",
"Server",
"Vary",
"WWW-Authenticate",
"Allow",
"Content-Encoding",
"Content-Language",
"Content-Length",
"Content-Location",
"Content-MD5",
"Content-Range",
"Content-Type",
"Expires",
"Last-Modified"
};
private object _Tag;
private object _syncobject;
private LineReadableSocketStream _st;
private bool _needclose;
private bool _isconnected;
private MyEndPoint _remoteep;
private int _requesttimeout;
private int _responsetimeout;
private MyHttpServerConnection.StreamStateType _req_state;
private bool _req_closed;
private string _req_method;
private MyHttpServerConnection.BodyLengthType _req_bodylengthtype;
private long _req_contentlength;
private string _req_currentheader;
private long _req_currentposition;
private int _req_currentchunksize;
private bool _req_expect100continue;
private MyHttpServerConnection.StreamStateType _res_state;
private bool _res_closed;
private MyHttpServerConnection.BodyLengthType _res_bodylengthtype;
private long _res_contentlength;
private bool _res_sentexpect100continue;
private long _res_currentposition;
private string _res_headers;
private bool disposedValue;
public MyHttpServerConnection(Socket basesocket)
{
this.disposedValue = false;
this._syncobject = RuntimeHelpers.GetObjectValue(new object());
this._remoteep = new MyEndPoint((IPEndPoint) basesocket.RemoteEndPoint);
this._st = new LineReadableSocketStream(basesocket);
this._needclose = false;
this._isconnected = true;
this._requesttimeout = 300000;
this._responsetimeout = 300000;
this._req_state = MyHttpServerConnection.StreamStateType.Initial;
this._req_closed = false;
this._res_state = MyHttpServerConnection.StreamStateType.Initial;
this._res_closed = false;
}
public LineReadableSocketStream BaseStream
{
get
{
return this._st;
}
set
{
this._st = value;
}
}
public int ReadTimeout
{
get
{
return this._st.ReadTimeout;
}
set
{
this._st.ReadTimeout = value;
}
}
public int WriteTimeout
{
get
{
return this._st.WriteTimeout;
}
set
{
this._st.WriteTimeout = value;
}
}
public int RequestTimeout
{
get
{
return this._requesttimeout;
}
set
{
this._requesttimeout = value;
}
}
public int ResponseTimeout
{
get
{
return this._responsetimeout;
}
set
{
this._responsetimeout = value;
}
}
public bool IsConnected
{
get
{
return this._isconnected;
}
}
public MyEndPoint RemoteEp
{
get
{
return this._remoteep;
}
}
public object Tag
{
get
{
return this._Tag;
}
set
{
this._Tag = RuntimeHelpers.GetObjectValue(value);
}
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue && disposing && this._st != null)
{
this._st.Close();
this._st = (LineReadableSocketStream) null;
}
this.disposedValue = true;
}
public void Close()
{
this.Dispose(true);
GC.SuppressFinalize((object) this);
}
public MyHttpServerRequest ReceiveRequest()
{
return this.ReceiveRequest(this.RequestTimeout);
}
public MyHttpServerRequest ReceiveRequest(int timeout)
{
IAsyncResult request = this.BeginReceiveRequest((AsyncCallback) null, (object) null);
if (!request.CompletedSynchronously && !request.AsyncWaitHandle.WaitOne(timeout, false))
throw new IOException("Timeout");
return this.EndReceiveRequest(request);
}
public IAsyncResult BeginReceiveRequest(AsyncCallback callback, object asyncstate)
{
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
if (this._req_state != MyHttpServerConnection.StreamStateType.Initial)
throw new InvalidOperationException();
this._req_state = MyHttpServerConnection.StreamStateType.Changing;
}
finally
{
Monitor.Exit(syncobject);
}
MyAsyncResult myAsyncResult = new MyAsyncResult(callback, RuntimeHelpers.GetObjectValue(asyncstate));
this._st.BeginReadLine(new AsyncCallback(this.OnRead_RequestLine), (object) myAsyncResult);
return (IAsyncResult) myAsyncResult;
}
private void OnRead_RequestLine(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
MyHttpServerRequest req = new MyHttpServerRequest();
asyncState.ReturnValue = (object) req;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
req._requestline = this._st.EndReadLine(asyncresult);
if (req._requestline == null)
asyncState.Complete();
else if (Operators.CompareString(req._requestline, "", false) == 0)
{
this._st.BeginReadLine(new AsyncCallback(this.OnRead_RequestLine), (object) asyncState);
}
else
{
string[] strArray = req._requestline.Split(new char[1]
{
' '
}, 3, StringSplitOptions.RemoveEmptyEntries);
if (strArray.Length < 2)
{
this.RequestStreamClose();
throw new MyHttpServerBadRequestException(req);
}
if (strArray[2].Length != 8)
{
this.RequestStreamClose();
throw new MyHttpServerBadRequestException(req);
}
if (string.Compare(strArray[2].Substring(0, 5), "HTTP/", StringComparison.InvariantCultureIgnoreCase) != 0)
{
this.RequestStreamClose();
throw new MyHttpServerBadRequestException(req);
}
float.Parse(strArray[2].Substring(5, 3));
req._method = strArray[0];
req._rawuri = strArray[1];
req._version = strArray[2];
this._req_method = req._method;
this._req_currentheader = (string) null;
this._st.BeginReadLine(new AsyncCallback(this.OnRead_Header), RuntimeHelpers.GetObjectValue(asyncresult.AsyncState));
}
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
}
}
private void OnRead_Header(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
MyHttpServerRequest returnValue = (MyHttpServerRequest) asyncState.ReturnValue;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
string Left = this._st.EndReadLine(asyncresult);
if (Left == null)
throw new MyHttpServerConnectionClosedException("Client Closed");
if (this._req_currentheader == null)
{
this._req_currentheader = Left;
this._st.BeginReadLine(new AsyncCallback(this.OnRead_Header), RuntimeHelpers.GetObjectValue(asyncresult.AsyncState));
return;
}
if (Left.Length > 0 && (Operators.CompareString(Conversions.ToString(Left[0]), " ", false) == 0 || Operators.CompareString(Conversions.ToString(Left[0]), "\t", false) == 0))
{
this._req_currentheader = this._req_currentheader + Left;
this._st.BeginReadLine(new AsyncCallback(this.OnRead_Header), RuntimeHelpers.GetObjectValue(asyncresult.AsyncState));
return;
}
int length = this._req_currentheader.IndexOf(":");
if (length < 0)
{
returnValue._requestheaders.Add(this._req_currentheader, "");
}
else
{
string name = this._req_currentheader.Substring(0, length).Trim();
string str = this._req_currentheader.Substring(checked (length + 1)).Trim();
returnValue._requestheaders.Add(name, str);
}
if (Operators.CompareString(Left, "", false) != 0)
{
this._req_currentheader = Left;
this._st.BeginReadLine(new AsyncCallback(this.OnRead_Header), RuntimeHelpers.GetObjectValue(asyncresult.AsyncState));
return;
}
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
return;
}
asyncState.Complete();
}
public MyHttpServerRequest EndReceiveRequest(IAsyncResult asyncresult)
{
MyAsyncResult myAsyncResult = (MyAsyncResult) asyncresult;
myAsyncResult.AsyncEnd();
MyHttpServerRequest returnValue = (MyHttpServerRequest) myAsyncResult.ReturnValue;
if (returnValue._requestline == null)
return (MyHttpServerRequest) null;
string requestheader1 = returnValue._requestheaders["Content-Length"];
if (requestheader1 != null)
{
if (!long.TryParse(requestheader1, out returnValue._contentlength))
returnValue._contentlength = 0L;
}
else
returnValue._contentlength = 0L;
this._req_contentlength = returnValue._contentlength;
string requestheader2 = returnValue._requestheaders["Transfer-Encoding"];
bool flag;
if (requestheader2 != null)
{
if (string.Compare(requestheader2.Trim(), "chunked", StringComparison.InvariantCultureIgnoreCase) != 0)
{
this.RequestStreamClose();
throw new MyHttpServerBadRequestException(returnValue);
}
flag = true;
}
else
flag = false;
string[] values1 = returnValue._requestheaders.GetValues("Connection");
if (values1 != null)
{
int num1 = 0;
int num2 = checked (values1.Length - 1);
int index = num1;
while (index <= num2)
{
if (string.Compare(values1[index], "Close", StringComparison.InvariantCultureIgnoreCase) == 0)
this._needclose = true;
checked { ++index; }
}
}
string[] values2 = returnValue._requestheaders.GetValues("Expect");
returnValue._expect100continue = false;
if (values2 != null)
{
int num1 = 0;
int num2 = checked (values2.Length - 1);
int index = num1;
while (index <= num2)
{
if (string.Compare(values2[index], "100-continue", StringComparison.InvariantCultureIgnoreCase) == 0)
returnValue._expect100continue = true;
checked { ++index; }
}
}
this._req_expect100continue = returnValue._expect100continue;
this._res_sentexpect100continue = false;
returnValue._host = returnValue._requestheaders["Host"];
if (returnValue._host == null)
{
this.RequestStreamClose();
throw new MyHttpServerBadRequestException(returnValue);
}
if (Operators.CompareString(returnValue._rawuri, "*", false) != 0 && !returnValue._rawuri.StartsWith("http://"))
{
if (returnValue._rawuri.StartsWith("/"))
{
if (!Uri.TryCreate("http://" + returnValue._host + returnValue._rawuri, UriKind.Absolute, out returnValue._requesturi))
throw new MyHttpServerBadRequestException(returnValue);
}
else
{
if (Operators.CompareString(returnValue.Method.ToUpperInvariant(), "CONNECT", false) != 0)
throw new MyHttpServerBadRequestException(returnValue);
if (!Uri.TryCreate("http://" + returnValue._rawuri, UriKind.Absolute, out returnValue._requesturi))
throw new MyHttpServerBadRequestException(returnValue);
if (returnValue._requesturi.Segments.Length != 1)
{
this.RequestStreamClose();
throw new MyHttpServerBadRequestException(returnValue);
}
}
}
if (flag)
this._req_bodylengthtype = MyHttpServerConnection.BodyLengthType.Chunk;
else if (returnValue._contentlength >= 0L)
{
this._req_bodylengthtype = MyHttpServerConnection.BodyLengthType.ContentLength;
}
else
{
this.RequestStreamClose();
throw new MyHttpServerBadRequestException(returnValue);
}
returnValue._reqstream = (Stream) new MyHttpServerConnection.RequestStream(this);
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
this._req_state = MyHttpServerConnection.StreamStateType.HeaderFinished;
if (returnValue._contentlength == 0L)
this._req_state = MyHttpServerConnection.StreamStateType.BodyFinished;
}
finally
{
Monitor.Exit(syncobject);
}
return returnValue;
}
private long RequestStreamLength()
{
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
if (this._req_state < MyHttpServerConnection.StreamStateType.HeaderFinished)
throw new InvalidOperationException();
}
finally
{
Monitor.Exit(syncobject);
}
return this._req_contentlength;
}
private long RequestStreamPosition()
{
return this._req_currentposition;
}
private IAsyncResult RequestStreamBeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
if (count < 0)
throw new ArgumentOutOfRangeException();
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
bool flag;
try
{
flag = this._req_state == MyHttpServerConnection.StreamStateType.BodyFinished;
if (!flag)
{
if (this._req_state != MyHttpServerConnection.StreamStateType.HeaderFinished)
throw new InvalidOperationException();
this._req_state = MyHttpServerConnection.StreamStateType.Changing;
}
if (this._req_expect100continue)
{
if (!this._res_sentexpect100continue)
{
if (!flag)
{
if (this._res_state != MyHttpServerConnection.StreamStateType.Initial)
throw new InvalidOperationException();
this._res_state = MyHttpServerConnection.StreamStateType.Changing;
}
}
}
}
finally
{
Monitor.Exit(syncobject);
}
MyAsyncResult mar = new MyAsyncResult(callback, RuntimeHelpers.GetObjectValue(state));
if (flag)
{
mar.ReturnValue = (object) 0;
mar.Complete();
return (IAsyncResult) mar;
}
mar.Tag = (object) new MyHttpServerConnection.StreamReadWriteParameter()
{
buffer = buffer,
offset = offset,
count = count
};
if (this._req_expect100continue && !this._res_sentexpect100continue)
{
byte[] bytes = Encoding.UTF8.GetBytes("HTTP/1.1 100 Continue\r\n\r\n");
this._st.BeginWrite(bytes, 0, bytes.Length, new AsyncCallback(this.OnRead_SendExpect100Continue), (object) mar);
}
else
this.InnerRequestStreamBeginRead2(mar);
return (IAsyncResult) mar;
}
private void OnRead_SendExpect100Continue(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
MyHttpServerConnection.StreamReadWriteParameter tag = (MyHttpServerConnection.StreamReadWriteParameter) asyncState.Tag;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
this._st.EndWrite(asyncresult);
this._res_sentexpect100continue = true;
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
this._res_state = MyHttpServerConnection.StreamStateType.Initial;
}
finally
{
Monitor.Exit(syncobject);
}
this.InnerRequestStreamBeginRead2(asyncState);
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
}
}
private void InnerRequestStreamBeginRead2(MyAsyncResult mar)
{
MyHttpServerConnection.StreamReadWriteParameter tag = (MyHttpServerConnection.StreamReadWriteParameter) mar.Tag;
switch (this._req_bodylengthtype)
{
case MyHttpServerConnection.BodyLengthType.Chunk:
if (this._req_currentchunksize == 0)
{
this._st.BeginReadLine(new AsyncCallback(this.OnRead_Body_ChunkSize), (object) mar);
break;
}
int count1 = tag.count;
if (count1 > this._req_currentchunksize)
count1 = this._req_currentchunksize;
this._st.BeginRead(tag.buffer, tag.offset, count1, new AsyncCallback(this.OnRead_Body_ChunkData), (object) mar);
break;
case MyHttpServerConnection.BodyLengthType.ContentLength:
int count2 = tag.count;
if (checked (this._req_currentposition + (long) count2) > this._req_contentlength)
count2 = checked ((int) (this._req_contentlength - this._req_currentposition));
this._st.BeginRead(tag.buffer, tag.offset, count2, new AsyncCallback(this.OnRead_Body_ContentLength), (object) mar);
break;
default:
this.RequestStreamClose();
throw new MyHttpServerBadRequestException((MyHttpServerRequest) null);
}
}
private void OnRead_Body_ContentLength(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
int num = this._st.EndRead(asyncresult);
if (num == 0)
throw new MyHttpServerConnectionClosedException("Client Closed");
this._req_currentposition = checked (this._req_currentposition + (long) num);
asyncState.ReturnValue = (object) num;
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
return;
}
asyncState.Complete();
}
private void OnRead_Body_ChunkSize(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
MyHttpServerConnection.StreamReadWriteParameter tag = (MyHttpServerConnection.StreamReadWriteParameter) asyncState.Tag;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
string str = this._st.EndReadLine(asyncresult);
if (str == null)
throw new MyHttpServerConnectionClosedException("Client Closed");
int length = str.IndexOf(";");
if (length >= 0)
str = str.Substring(0, length);
if (!int.TryParse(str.Trim(), NumberStyles.AllowHexSpecifier, (IFormatProvider) null, out this._req_currentchunksize))
{
this.RequestStreamClose();
throw new MyHttpServerBadRequestException((MyHttpServerRequest) null);
}
if (this._req_currentchunksize == 0)
{
this._st.BeginReadLine(new AsyncCallback(this.OnRead_Body_ChunkTrailer), (object) asyncState);
}
else
{
int count = tag.count;
if (count > this._req_currentchunksize)
count = this._req_currentchunksize;
this._st.BeginRead(tag.buffer, tag.offset, count, new AsyncCallback(this.OnRead_Body_ChunkData), (object) asyncState);
}
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
}
}
private void OnRead_Body_ChunkData(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
int num = this._st.EndRead(asyncresult);
if (num == 0)
{
this.RequestStreamClose();
throw new MyHttpServerBadRequestException((MyHttpServerRequest) null);
}
this._req_currentchunksize = checked (this._req_currentchunksize - num);
this._req_currentposition = checked (this._req_currentposition + (long) num);
asyncState.ReturnValue = (object) num;
this._st.BeginReadLine(new AsyncCallback(this.OnRead_Body_ChunkDataEnd), (object) asyncState);
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
}
}
private void OnRead_Body_ChunkDataEnd(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
this._st.EndReadLine((IAsyncResult) asyncState);
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
return;
}
asyncState.Complete();
}
private void OnRead_Body_ChunkTrailer(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
if (this._st.EndReadLine((IAsyncResult) asyncState).Length == 0)
{
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
this._req_state = MyHttpServerConnection.StreamStateType.BodyFinished;
}
finally
{
Monitor.Exit(syncobject);
}
asyncState.ReturnValue = (object) 0;
asyncState.Complete();
}
else
this._st.BeginReadLine(new AsyncCallback(this.OnRead_Body_ChunkTrailer), (object) asyncState);
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
return;
}
asyncState.Complete();
}
private int RequestStreamEndRead(IAsyncResult asyncResult)
{
MyAsyncResult myAsyncResult = (MyAsyncResult) asyncResult;
myAsyncResult.AsyncEnd();
int returnValue = (int) myAsyncResult.ReturnValue;
if (returnValue == 0 && this._req_state != MyHttpServerConnection.StreamStateType.BodyFinished)
throw new MyHttpServerBadRequestException((MyHttpServerRequest) null);
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
this._req_state = MyHttpServerConnection.StreamStateType.HeaderFinished;
if (this._req_currentposition >= this._req_contentlength)
this._req_state = MyHttpServerConnection.StreamStateType.BodyFinished;
}
finally
{
Monitor.Exit(syncobject);
}
return returnValue;
}
public Stream SendResponse(MyHttpServerResponse response)
{
return this.SendResponse(response, this.ResponseTimeout);
}
public Stream SendResponse(MyHttpServerResponse response, int timeout)
{
IAsyncResult asyncresult = this.BeginSendResponse(response, (AsyncCallback) null, (object) null);
if (!asyncresult.CompletedSynchronously && !asyncresult.AsyncWaitHandle.WaitOne(timeout, false))
throw new IOException("Timeout");
return this.EndSendResponse(asyncresult);
}
public IAsyncResult BeginSendResponse(MyHttpServerResponse response, AsyncCallback callback, object asyncstate)
{
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
if (this._res_state != MyHttpServerConnection.StreamStateType.Initial)
throw new InvalidOperationException();
this._res_state = MyHttpServerConnection.StreamStateType.Changing;
}
finally
{
Monitor.Exit(syncobject);
}
MyAsyncResult myAsyncResult = new MyAsyncResult(callback, RuntimeHelpers.GetObjectValue(asyncstate));
NameValueCollection nameValueCollection = new NameValueCollection(response._responseheaders);
if (Operators.CompareString(this._req_method, "HEAD", false) == 0)
{
this._res_bodylengthtype = MyHttpServerConnection.BodyLengthType.NoBody;
this._res_contentlength = response._contentlength;
}
else if (response._statuscode == 204 || response._statuscode == 304)
{
this._res_bodylengthtype = MyHttpServerConnection.BodyLengthType.ContentLength;
this._res_contentlength = 0L;
}
else if (response._sendchunked)
{
this._res_bodylengthtype = MyHttpServerConnection.BodyLengthType.Chunk;
this._res_contentlength = -1L;
}
else
{
if (response._contentlength < 0L)
throw new Exception();
this._res_bodylengthtype = MyHttpServerConnection.BodyLengthType.ContentLength;
this._res_contentlength = response._contentlength;
}
if (string.IsNullOrEmpty(response._statusdesc))
{
switch (response.StatusCode)
{
case 200:
response._statusdesc = "OK";
break;
case 201:
response._statusdesc = "Created";
break;
case 202:
response._statusdesc = "Accepted";
break;
case 203:
response._statusdesc = "Non-Authoritative Information";
break;
case 204:
response._statusdesc = "No Content";
break;
case 205:
response._statusdesc = "Reset Content";
break;
case 206:
response._statusdesc = "Partial Content";
break;
case 207:
response._statusdesc = "Multi-Status";
break;
case 300:
response._statusdesc = "Multiple Choices";
break;
case 301:
response._statusdesc = "Moved Permanently";
break;
case 302:
response._statusdesc = "Found";
break;
case 303:
response._statusdesc = "See Other";
break;
case 304:
response._statusdesc = "Not Modified";
break;
case 305:
response._statusdesc = "Use Proxy";
break;
case 306:
response._statusdesc = "(Unused)";
break;
case 307:
response._statusdesc = "Temporary Redirect";
break;
case 400:
response._statusdesc = "Bad Request";
break;
case 401:
response._statusdesc = "Unauthorized";
break;
case 402:
response._statusdesc = "Payment Required";
break;
case 403:
response._statusdesc = "Forbidden";
break;
case 404:
response._statusdesc = "Not Found";
break;
case 405:
response._statusdesc = "Method Not Allowed";
break;
case 406:
response._statusdesc = "Not Acceptable";
break;
case 407:
response._statusdesc = "Proxy Authentication Required";
break;
case 408:
response._statusdesc = "Request Timeout";
break;
case 409:
response._statusdesc = "Conflict";
break;
case 410:
response._statusdesc = "Gone";
break;
case 411:
response._statusdesc = "Length Required";
break;
case 412:
response._statusdesc = "Precondition Failed";
break;
case 413:
response._statusdesc = "Request Entity Too Large";
break;
case 414:
response._statusdesc = "Request-URI Too Long";
break;
case 415:
response._statusdesc = "Unsupported Media Type";
break;
case 416:
response._statusdesc = "Requested Range Not Satisfiable";
break;
case 417:
response._statusdesc = "Expectation Failed";
break;
case 422:
response._statusdesc = "Unprocessable Entity";
break;
case 423:
response._statusdesc = "Locked";
break;
case 424:
response._statusdesc = "Failed Dependency";
break;
case 500:
response._statusdesc = "Internal Server Error";
break;
case 501:
response._statusdesc = "Not Implemented";
break;
case 502:
response._statusdesc = "Bad Gateway";
break;
case 503:
response._statusdesc = "Service Unavailable";
break;
case 504:
response._statusdesc = "Gateway Timeout";
break;
case 505:
response._statusdesc = "HTTP Version Not Supported";
break;
case 506:
response._statusdesc = "Variant Also Negotiates";
break;
case 507:
response._statusdesc = "Insufficient Storage";
break;
default:
response._statusdesc = "";
break;
}
}
string str1 = string.Join(" ", new string[3]
{
"HTTP/1.1",
response._statuscode.ToString(),
response._statusdesc
});
if (this._needclose)
nameValueCollection.Add("Connection", "Close");
string[] values1 = nameValueCollection.GetValues("Connection");
if (values1 != null)
{
int num1 = 0;
int num2 = checked (values1.Length - 1);
int index = num1;
while (index <= num2)
{
if (string.Compare(values1[index], "Close", StringComparison.InvariantCultureIgnoreCase) == 0)
this._needclose = true;
checked { ++index; }
}
}
if (nameValueCollection["Transfer-Encoding"] != null && Operators.CompareString(nameValueCollection["Transfer-Encoding"], "chunked", false) != 0)
throw new NotImplementedException();
if (response._sendchunked)
nameValueCollection["Transfer-Encoding"] = "chunked";
if (nameValueCollection["Date"] == null)
nameValueCollection.Add("Date", DateTime.Now.ToUniversalTime().ToString("r"));
if (this._res_bodylengthtype == MyHttpServerConnection.BodyLengthType.Chunk)
nameValueCollection.Remove("Content-Length");
else
nameValueCollection["Content-Length"] = this._res_contentlength.ToString();
List<string> stringList = new List<string>();
stringList.Add(str1);
string[] headerOrder = MyHttpServerConnection.HeaderOrder;
int index1 = 0;
while (index1 < headerOrder.Length)
{
string name = headerOrder[index1];
string str2 = nameValueCollection.Get(name);
if (str2 != null)
{
stringList.Add(name + ": " + str2.Trim());
nameValueCollection.Remove(name);
}
checked { ++index1; }
}
try
{
foreach (object key in nameValueCollection.Keys)
{
string str2 = Conversions.ToString(key);
string str3 = nameValueCollection.Get(str2);
if (string.Compare(str2, "Set-Cookie", StringComparison.InvariantCultureIgnoreCase) == 0)
{
string[] values2 = nameValueCollection.GetValues(str2);
int index2 = 0;
while (index2 < values2.Length)
{
string str4 = values2[index2];
stringList.Add(str2 + ": " + str4.Trim());
checked { ++index2; }
}
}
else
stringList.Add(str2 + ": " + str3.Trim());
}
}
finally
{
IEnumerator enumerator;
if (enumerator is IDisposable)
(enumerator as IDisposable).Dispose();
}
stringList.Add("");
stringList.Add("");
this._res_headers = string.Join("\r\n", stringList.ToArray());
byte[] bytes = Encoding.UTF8.GetBytes(this._res_headers);
this._st.BeginWrite(bytes, 0, bytes.Length, new AsyncCallback(this.OnSend_Header), (object) myAsyncResult);
return (IAsyncResult) myAsyncResult;
}
private void OnSend_Header(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
this._st.EndWrite(asyncresult);
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
return;
}
asyncState.Complete();
}
public Stream EndSendResponse(IAsyncResult asyncresult)
{
MyAsyncResult myAsyncResult = (MyAsyncResult) asyncresult;
myAsyncResult.AsyncEnd();
myAsyncResult.ReturnValue = (object) new MyHttpServerConnection.ResponseStream(this);
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
this._res_state = MyHttpServerConnection.StreamStateType.HeaderFinished;
if (this._res_bodylengthtype != MyHttpServerConnection.BodyLengthType.NoBody)
{
if (this._res_bodylengthtype == MyHttpServerConnection.BodyLengthType.ContentLength)
{
if (this._res_contentlength != 0L)
goto label_6;
}
else
goto label_6;
}
this._res_state = MyHttpServerConnection.StreamStateType.BodyFinished;
}
finally
{
Monitor.Exit(syncobject);
}
label_6:
return (Stream) myAsyncResult.ReturnValue;
}
private long ResponseStreamLength()
{
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
if (this._res_state < MyHttpServerConnection.StreamStateType.HeaderFinished)
throw new InvalidOperationException();
}
finally
{
Monitor.Exit(syncobject);
}
return this._res_contentlength;
}
private long ResponseStreamPosition()
{
return this._res_currentposition;
}
private IAsyncResult ResponseStreamBeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
if (count < 0)
throw new ArgumentOutOfRangeException();
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
if (this._res_state == MyHttpServerConnection.StreamStateType.BodyFinished)
throw new InvalidOperationException("message body is finished");
if (this._res_state != MyHttpServerConnection.StreamStateType.HeaderFinished)
throw new InvalidOperationException();
this._res_state = MyHttpServerConnection.StreamStateType.Changing;
}
finally
{
Monitor.Exit(syncobject);
}
MyAsyncResult myAsyncResult = new MyAsyncResult(callback, RuntimeHelpers.GetObjectValue(state));
MyHttpServerConnection.StreamReadWriteParameter readWriteParameter = new MyHttpServerConnection.StreamReadWriteParameter();
readWriteParameter.buffer = buffer;
readWriteParameter.offset = offset;
readWriteParameter.count = count;
myAsyncResult.Tag = (object) readWriteParameter;
switch (this._res_bodylengthtype)
{
case MyHttpServerConnection.BodyLengthType.NoBody:
myAsyncResult.Complete();
return (IAsyncResult) myAsyncResult;
case MyHttpServerConnection.BodyLengthType.Chunk:
if (readWriteParameter.count == 0)
{
myAsyncResult.Complete();
return (IAsyncResult) myAsyncResult;
}
byte[] bytes = Encoding.UTF8.GetBytes(readWriteParameter.count.ToString("x") + "\r\n");
this._st.BeginWrite(bytes, 0, bytes.Length, new AsyncCallback(this.OnSend_Body_Chunk_Size), (object) myAsyncResult);
break;
case MyHttpServerConnection.BodyLengthType.ContentLength:
if (checked ((long) readWriteParameter.count + this._res_currentposition) > this._res_contentlength)
throw new IOException("Content length is not match");
this._st.BeginWrite(readWriteParameter.buffer, readWriteParameter.offset, readWriteParameter.count, new AsyncCallback(this.OnSend_Body_ContentLength), (object) myAsyncResult);
break;
default:
throw new Exception();
}
return (IAsyncResult) myAsyncResult;
}
private void OnSend_Body_Chunk_Size(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
MyHttpServerConnection.StreamReadWriteParameter tag = (MyHttpServerConnection.StreamReadWriteParameter) asyncState.Tag;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
this._st.EndWrite(asyncresult);
this._st.BeginWrite(tag.buffer, tag.offset, tag.count, new AsyncCallback(this.OnSend_Body_Chunk_Data), (object) asyncState);
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
}
}
private void OnSend_Body_Chunk_Data(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
MyHttpServerConnection.StreamReadWriteParameter tag = (MyHttpServerConnection.StreamReadWriteParameter) asyncState.Tag;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
this._st.EndWrite(asyncresult);
this._res_currentposition = checked (this._res_currentposition + (long) tag.count);
byte[] buffer = new byte[2]{ (byte) 13, (byte) 10 };
this._st.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(this.OnSend_Body_Chunk_Data_End), (object) asyncState);
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
}
}
private void OnSend_Body_Chunk_Data_End(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
MyHttpServerConnection.StreamReadWriteParameter tag = (MyHttpServerConnection.StreamReadWriteParameter) asyncState.Tag;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
this._st.EndWrite(asyncresult);
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
this._res_state = MyHttpServerConnection.StreamStateType.HeaderFinished;
}
finally
{
Monitor.Exit(syncobject);
}
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
return;
}
asyncState.Complete();
}
private void OnSend_Body_ContentLength(IAsyncResult asyncresult)
{
MyAsyncResult asyncState = (MyAsyncResult) asyncresult.AsyncState;
MyHttpServerConnection.StreamReadWriteParameter tag = (MyHttpServerConnection.StreamReadWriteParameter) asyncState.Tag;
if (!asyncresult.CompletedSynchronously)
asyncState.SetAsync();
try
{
this._st.EndWrite(asyncresult);
this._res_currentposition = checked (this._res_currentposition + (long) tag.count);
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
if (this._res_currentposition == this._res_contentlength)
this._res_state = MyHttpServerConnection.StreamStateType.BodyFinished;
else if (this._res_currentposition > this._res_contentlength)
asyncState.Complete(new Exception());
else
this._res_state = MyHttpServerConnection.StreamStateType.HeaderFinished;
}
finally
{
Monitor.Exit(syncobject);
}
}
catch (Exception ex1)
{
ProjectData.SetProjectError(ex1);
Exception ex2 = ex1;
asyncState.Complete(ex2);
ProjectData.ClearProjectError();
return;
}
asyncState.Complete();
}
private void ResponseStreamEndWrite(IAsyncResult asyncResult)
{
((MyAsyncResult) asyncResult).AsyncEnd();
}
internal void RequestStreamClose()
{
this._req_closed = true;
if (!this._res_closed)
return;
this.CloseSeries();
}
private void ResponseStreamClose()
{
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
if (this._res_state == MyHttpServerConnection.StreamStateType.HeaderFinished && this._res_bodylengthtype == MyHttpServerConnection.BodyLengthType.Chunk)
{
this._res_state = MyHttpServerConnection.StreamStateType.Changing;
byte[] bytes = Encoding.UTF8.GetBytes("0\r\n\r\n");
this._st.EndWrite(this._st.BeginWrite(bytes, 0, bytes.Length, (AsyncCallback) null, (object) null));
this._res_state = MyHttpServerConnection.StreamStateType.BodyFinished;
}
else if (this._res_bodylengthtype == MyHttpServerConnection.BodyLengthType.ContentLength)
{
if (this._res_state != MyHttpServerConnection.StreamStateType.BodyFinished)
throw new Exception();
}
}
finally
{
Monitor.Exit(syncobject);
}
this._res_closed = true;
if (!this._req_closed)
return;
this.CloseSeries();
}
private void CloseSeries()
{
if (!this._res_closed || !this._req_closed)
return;
this._needclose = this._needclose | this._req_state != MyHttpServerConnection.StreamStateType.BodyFinished;
this._needclose = this._needclose | this._res_state != MyHttpServerConnection.StreamStateType.BodyFinished;
if (this._needclose)
{
this._st.Close();
this._st = (LineReadableSocketStream) null;
this._isconnected = false;
}
else
{
object syncobject = this._syncobject;
ObjectFlowControl.CheckForSyncLockOnValueType(syncobject);
Monitor.Enter(syncobject);
try
{
this._res_currentposition = 0L;
this._req_currentposition = 0L;
this._req_currentchunksize = 0;
this._req_closed = false;
this._res_closed = false;
this._req_state = MyHttpServerConnection.StreamStateType.Initial;
this._res_state = MyHttpServerConnection.StreamStateType.Initial;
}
finally
{
Monitor.Exit(syncobject);
}
}
}
public override string ToString()
{
string str = base.ToString();
if (!this.IsConnected)
return str + "\r\nDicsonnected";
return str + "\r\n" + this._remoteep.ToString() + "\r\n" + this._req_state.ToString();
}
private enum BodyLengthType
{
Unknown,
NoBody,
Chunk,
ContentLength,
Connection,
}
private enum StreamStateType
{
Changing,
Initial,
HeaderFinished,
BodyFinished,
}
private class StreamReadWriteParameter
{
public byte[] buffer;
public int offset;
public int count;
[DebuggerNonUserCode]
public StreamReadWriteParameter()
{
}
}
private class RequestStream : Stream
{
private MyHttpServerConnection _owner;
public RequestStream(MyHttpServerConnection owner)
{
this._owner = owner;
}
public override void Close()
{
if (this._owner != null)
this._owner.RequestStreamClose();
this._owner = (MyHttpServerConnection) null;
base.Close();
}
public override bool CanRead
{
get
{
return true;
}
}
public override bool CanSeek
{
get
{
return false;
}
}
public override bool CanWrite
{
get
{
return false;
}
}
public override void Flush()
{
throw new NotImplementedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
public override long Length
{
get
{
if (this._owner == null)
throw new ObjectDisposedException(this.ToString());
return this._owner.RequestStreamLength();
}
}
public override long Position
{
get
{
if (this._owner == null)
throw new ObjectDisposedException(this.ToString());
return this._owner.RequestStreamPosition();
}
set
{
throw new NotImplementedException();
}
}
public override int Read(byte[] buffer, int offset, int count)
{
IAsyncResult asyncResult = this._owner.RequestStreamBeginRead(buffer, offset, count, (AsyncCallback) null, (object) null);
if (!asyncResult.CompletedSynchronously && !asyncResult.AsyncWaitHandle.WaitOne(this._owner.ReadTimeout, false))
throw new IOException("Timeout");
return this._owner.RequestStreamEndRead(asyncResult);
}
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
return this._owner.RequestStreamBeginRead(buffer, offset, count, callback, RuntimeHelpers.GetObjectValue(state));
}
public override int EndRead(IAsyncResult asyncResult)
{
return this._owner.RequestStreamEndRead(asyncResult);
}
public override int ReadTimeout
{
get
{
return this._owner.ReadTimeout;
}
set
{
this._owner.ReadTimeout = value;
}
}
public override int WriteTimeout
{
get
{
return this._owner.WriteTimeout;
}
set
{
this._owner.WriteTimeout = value;
}
}
}
private class ResponseStream : Stream
{
private MyHttpServerConnection _owner;
public ResponseStream(MyHttpServerConnection owner)
{
this._owner = owner;
}
public override void Close()
{
if (this._owner != null)
this._owner.ResponseStreamClose();
this._owner = (MyHttpServerConnection) null;
base.Close();
}
public override bool CanRead
{
get
{
return false;
}
}
public override bool CanSeek
{
get
{
return false;
}
}
public override bool CanWrite
{
get
{
return true;
}
}
public override void Flush()
{
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override long Length
{
get
{
if (this._owner == null)
throw new ObjectDisposedException(this.ToString());
return this._owner.ResponseStreamLength();
}
}
public override long Position
{
get
{
if (this._owner == null)
throw new ObjectDisposedException(this.ToString());
return this._owner.ResponseStreamPosition();
}
set
{
throw new NotImplementedException();
}
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
IAsyncResult asyncResult = this._owner.ResponseStreamBeginWrite(buffer, offset, count, (AsyncCallback) null, (object) null);
if (!asyncResult.CompletedSynchronously && !asyncResult.AsyncWaitHandle.WaitOne(this._owner.WriteTimeout, false))
throw new IOException("Timeout");
this._owner.ResponseStreamEndWrite(asyncResult);
}
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
return this._owner.ResponseStreamBeginWrite(buffer, offset, count, callback, RuntimeHelpers.GetObjectValue(state));
}
public override void EndWrite(IAsyncResult asyncResult)
{
this._owner.ResponseStreamEndWrite(asyncResult);
}
public override int ReadTimeout
{
get
{
return this._owner.ReadTimeout;
}
set
{
this._owner.ReadTimeout = value;
}
}
public override int WriteTimeout
{
get
{
return this._owner.WriteTimeout;
}
set
{
this._owner.WriteTimeout = value;
}
}
}
}
}