mirror of
https://github.com/opensim/opensim.git
synced 2026-08-01 06:06:06 +08:00
oshttp send: modern TAP is still just a complex wrapper of 'obsolete' APM hidding at IL level, so just use the 'obsolete'
This commit is contained in:
@@ -4,7 +4,6 @@ using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OSHttpServer.Exceptions;
|
||||
using OSHttpServer.Parser;
|
||||
using System.Net.Security;
|
||||
@@ -531,11 +530,11 @@ namespace OSHttpServer
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ContinueSendResponse(bool notThrottled)
|
||||
public void ContinueSendResponse()
|
||||
{
|
||||
if(m_currentResponse == null)
|
||||
return;
|
||||
ContextTimeoutManager.EnqueueSend(this, m_currentResponse.Priority, notThrottled);
|
||||
ContextTimeoutManager.EnqueueSend(this, m_currentResponse.Priority, true);
|
||||
}
|
||||
|
||||
public void EndSendResponse(uint requestID, ConnectionType ctype)
|
||||
@@ -678,7 +677,23 @@ namespace OSHttpServer
|
||||
return ok;
|
||||
}
|
||||
|
||||
public async Task<bool> SendAsync(byte[] buffer, int offset, int size)
|
||||
private void SendAsyncEnd(IAsyncResult res)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_stream.EndWrite(res);
|
||||
m_currentResponse.CheckSendNextAsyncContinue();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.GetHashCode();
|
||||
if(m_stream != null)
|
||||
Disconnect(SocketError.NoRecovery);
|
||||
}
|
||||
ContextTimeoutManager.ContextLeaveActiveSend();
|
||||
}
|
||||
|
||||
public bool SendAsyncStart(byte[] buffer, int offset, int size)
|
||||
{
|
||||
if (m_stream == null || m_sock == null || !m_sock.Connected)
|
||||
return false;
|
||||
@@ -690,15 +705,15 @@ namespace OSHttpServer
|
||||
ContextTimeoutManager.ContextEnterActiveSend();
|
||||
try
|
||||
{
|
||||
await m_stream.WriteAsync(buffer, offset, size).ConfigureAwait(false);
|
||||
m_stream.BeginWrite(buffer, offset, size, SendAsyncEnd, null);
|
||||
}
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
e.GetHashCode();
|
||||
ContextTimeoutManager.ContextLeaveActiveSend();
|
||||
ok = false;
|
||||
}
|
||||
|
||||
ContextTimeoutManager.ContextLeaveActiveSend();
|
||||
|
||||
if (!ok && m_stream != null)
|
||||
Disconnect(SocketError.NoRecovery);
|
||||
return ok;
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace OSHttpServer
|
||||
{
|
||||
public class HttpResponse : IHttpResponse
|
||||
{
|
||||
public event EventHandler<BandWitdhEventArgs> BandWitdhEvent;
|
||||
|
||||
private const string DefaultContentType = "text/html;charset=UTF-8";
|
||||
private readonly IHttpClientContext m_context;
|
||||
private readonly ResponseCookies m_cookies = new ResponseCookies();
|
||||
@@ -237,7 +235,8 @@ namespace OSHttpServer
|
||||
long len = m_contentLength;
|
||||
if (len == 0)
|
||||
{
|
||||
len = Body.Length;
|
||||
if(m_body!= null)
|
||||
len = m_body.Length;
|
||||
if (RawBuffer != null && RawBufferLen > 0)
|
||||
len += RawBufferLen;
|
||||
}
|
||||
@@ -341,155 +340,155 @@ namespace OSHttpServer
|
||||
RawBufferStart = 0;
|
||||
RawBufferLen = tlen;
|
||||
}
|
||||
|
||||
if (RawBufferLen == 0)
|
||||
RawBuffer = null;
|
||||
}
|
||||
|
||||
if (m_body != null && m_body.Length == 0)
|
||||
{
|
||||
m_body.Dispose();
|
||||
m_body = null;
|
||||
}
|
||||
|
||||
if (m_headerBytes == null && RawBuffer == null && m_body == null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
m_context.StartSendResponse(this);
|
||||
}
|
||||
|
||||
public async Task SendNextAsync(int bytesLimit)
|
||||
public void SendNextAsync(int bytesLimit)
|
||||
{
|
||||
if (m_headerBytes != null)
|
||||
{
|
||||
if(!await m_context.SendAsync(m_headerBytes, 0, m_headerBytes.Length).ConfigureAwait(false))
|
||||
byte[] b = m_headerBytes;
|
||||
m_headerBytes = null;
|
||||
|
||||
if (!m_context.SendAsyncStart(b, 0, b.Length))
|
||||
{
|
||||
if (m_body != null)
|
||||
{
|
||||
m_body.Dispose();
|
||||
m_body = null;
|
||||
}
|
||||
RawBuffer = null;
|
||||
Sent = true;
|
||||
return;
|
||||
}
|
||||
bytesLimit -= m_headerBytes.Length;
|
||||
m_headerBytes = null;
|
||||
if(bytesLimit <= 0)
|
||||
{
|
||||
m_context.ContinueSendResponse(false);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool sendRes;
|
||||
if (RawBuffer != null && RawBufferLen > 0)
|
||||
if (RawBuffer != null)
|
||||
{
|
||||
if (BandWitdhEvent != null)
|
||||
{
|
||||
bytesLimit = CheckBandwidth(RawBufferLen, bytesLimit);
|
||||
if (bytesLimit <= 0)
|
||||
{
|
||||
m_context.ContinueSendResponse(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(RawBufferLen > bytesLimit)
|
||||
{
|
||||
sendRes = (await m_context.SendAsync(RawBuffer, RawBufferStart, bytesLimit).ConfigureAwait(false));
|
||||
if (sendRes)
|
||||
{
|
||||
RawBufferLen -= bytesLimit;
|
||||
RawBufferStart += bytesLimit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sendRes = await m_context.SendAsync(RawBuffer, RawBufferStart, RawBufferLen).ConfigureAwait(false);
|
||||
if(sendRes)
|
||||
RawBufferLen = 0;
|
||||
}
|
||||
|
||||
if (!sendRes)
|
||||
{
|
||||
RawBuffer = null;
|
||||
if(m_body != null)
|
||||
Body.Dispose();
|
||||
Sent = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (RawBufferLen <= 0)
|
||||
RawBuffer = null;
|
||||
else
|
||||
{
|
||||
m_context.ContinueSendResponse(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_body != null && m_body.Length != 0)
|
||||
{
|
||||
MemoryStream mb = m_body as MemoryStream;
|
||||
RawBuffer = mb.GetBuffer();
|
||||
RawBufferStart = 0; // must be a internal buffer, or starting at 0
|
||||
RawBufferLen = (int)mb.Length;
|
||||
mb.Dispose();
|
||||
m_body = null;
|
||||
|
||||
if(RawBufferLen > 0)
|
||||
{
|
||||
if (BandWitdhEvent != null)
|
||||
{
|
||||
bytesLimit = CheckBandwidth(RawBufferLen, bytesLimit);
|
||||
if (bytesLimit <= 0)
|
||||
{
|
||||
m_context.ContinueSendResponse(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
byte[] b = RawBuffer;
|
||||
int s = RawBufferStart;
|
||||
|
||||
if (RawBufferLen > bytesLimit)
|
||||
{
|
||||
sendRes = await m_context.SendAsync(RawBuffer, RawBufferStart, bytesLimit).ConfigureAwait(false);
|
||||
if (sendRes)
|
||||
{
|
||||
RawBufferLen -= bytesLimit;
|
||||
RawBufferStart += bytesLimit;
|
||||
}
|
||||
RawBufferLen -= bytesLimit;
|
||||
RawBufferStart += bytesLimit;
|
||||
if (RawBufferLen <= 0)
|
||||
RawBuffer = null;
|
||||
sendRes = m_context.SendAsyncStart(b, s, bytesLimit);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendRes = await m_context.SendAsync(RawBuffer, RawBufferStart, RawBufferLen).ConfigureAwait(false);
|
||||
if (sendRes)
|
||||
RawBufferLen = 0;
|
||||
int l = RawBufferLen;
|
||||
RawBufferLen = 0;
|
||||
RawBuffer = null;
|
||||
sendRes = m_context.SendAsyncStart(b, s, l);
|
||||
}
|
||||
|
||||
if (!sendRes)
|
||||
{
|
||||
RawBuffer = null;
|
||||
if(m_body != null)
|
||||
{
|
||||
m_body.Dispose();
|
||||
m_body = null;
|
||||
}
|
||||
Sent = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (RawBufferLen > 0)
|
||||
{
|
||||
m_context.ContinueSendResponse(false);
|
||||
return;
|
||||
}
|
||||
else
|
||||
RawBuffer = null;
|
||||
}
|
||||
|
||||
if (m_body != null)
|
||||
m_body.Dispose();
|
||||
{
|
||||
if(m_body.Length != 0)
|
||||
{
|
||||
MemoryStream mb = m_body as MemoryStream;
|
||||
RawBuffer = mb.GetBuffer();
|
||||
RawBufferStart = 0; // must be a internal buffer, or starting at 0
|
||||
RawBufferLen = (int)mb.Length;
|
||||
m_body.Dispose();
|
||||
m_body = null;
|
||||
|
||||
if (RawBufferLen > 0)
|
||||
{
|
||||
byte[] b = RawBuffer;
|
||||
int s = RawBufferStart;
|
||||
|
||||
if (RawBufferLen > bytesLimit)
|
||||
{
|
||||
RawBufferLen -= bytesLimit;
|
||||
RawBufferStart += bytesLimit;
|
||||
if (RawBufferLen <= 0)
|
||||
RawBuffer = null;
|
||||
sendRes = m_context.SendAsyncStart(b, s, bytesLimit);
|
||||
}
|
||||
else
|
||||
{
|
||||
int l = RawBufferLen;
|
||||
sendRes = m_context.SendAsyncStart(b, s, l);
|
||||
RawBufferLen = 0;
|
||||
RawBuffer = null;
|
||||
}
|
||||
|
||||
if (!sendRes)
|
||||
{
|
||||
RawBuffer = null;
|
||||
Sent = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
RawBuffer = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_body.Dispose();
|
||||
m_body = null;
|
||||
}
|
||||
}
|
||||
|
||||
Sent = true;
|
||||
m_context.EndSendResponse(requestID, Connection);
|
||||
}
|
||||
|
||||
private int CheckBandwidth(int request, int bytesLimit)
|
||||
public void CheckSendNextAsyncContinue()
|
||||
{
|
||||
if (request > bytesLimit)
|
||||
request = bytesLimit;
|
||||
var args = new BandWitdhEventArgs(request);
|
||||
try
|
||||
if(m_headerBytes == null && RawBuffer == null && m_body == null)
|
||||
{
|
||||
BandWitdhEvent?.Invoke(this, args);
|
||||
return args.Result;
|
||||
Sent = true;
|
||||
m_context.EndSendResponse(requestID, Connection);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_context.ContinueSendResponse();
|
||||
}
|
||||
catch { }
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if(Body != null && Body.CanRead)
|
||||
Body.Dispose();
|
||||
if(m_body != null && m_body.CanRead)
|
||||
m_body.Dispose();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace OSHttpServer
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
bool Send(byte[] buffer, int offset, int size);
|
||||
Task<bool> SendAsync(byte[] buffer, int offset, int size);
|
||||
bool SendAsyncStart(byte[] buffer, int offset, int size);
|
||||
|
||||
/// <summary>
|
||||
/// Closes the streams and disposes of the unmanaged resources
|
||||
@@ -95,7 +95,7 @@ namespace OSHttpServer
|
||||
HTTPNetworkContext GiveMeTheNetworkStreamIKnowWhatImDoing();
|
||||
|
||||
void StartSendResponse(HttpResponse response);
|
||||
void ContinueSendResponse(bool notThrottled);
|
||||
void ContinueSendResponse();
|
||||
void EndSendResponse(uint requestID, ConnectionType connection);
|
||||
bool TrySendResponse(int limit);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace OSHttpServer
|
||||
/// </example>
|
||||
public interface IHttpResponse
|
||||
{
|
||||
event EventHandler<BandWitdhEventArgs> BandWitdhEvent;
|
||||
/// <summary>
|
||||
/// The body stream is used to cache the body contents
|
||||
/// before sending everything to the client. It's the simplest
|
||||
@@ -145,19 +144,4 @@ namespace OSHttpServer
|
||||
/// </summary>
|
||||
KeepAlive
|
||||
}
|
||||
|
||||
public class BandWitdhEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets received request.
|
||||
/// </summary>
|
||||
public int Result;
|
||||
public int Request;
|
||||
|
||||
public BandWitdhEventArgs(int request)
|
||||
{
|
||||
Request = request;
|
||||
Result = request;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user