internal bool Return(Stream stream, Socket socket, bool forceFlush)
{
var offset = offsetInOutput;
int responseCode = (int)ResponseStatus;
var http = HttpResponse[responseCode - 100];
Buffer.BlockCopy(http, 0, OutputTemp, offset, http.Length);
offset += http.Length;
if (ResponseIsJson)
{
Buffer.BlockCopy(JsonContentType, 0, OutputTemp, offset, JsonContentType.Length);
offset += JsonContentType.Length;
}
else if (ResponseContentType != null)
{
offset = AddContentType(ResponseContentType, offset);
}
for (int x = 0; x < ResponseHeadersLength; x++)
{
var kv = ResponseHeaders[x];
var val = kv.Key;
for (int i = 0; i < val.Length; i++)
OutputTemp[offset + i] = (byte)val[i];
offset += val.Length;
OutputTemp[offset++] = 58;
OutputTemp[offset++] = 32;
val = kv.Value;
for (int i = 0; i < val.Length; i++)
OutputTemp[offset + i] = (byte)val[i];
offset += val.Length;
OutputTemp[offset++] = 13;
OutputTemp[offset++] = 10;
}
bool keepAlive;
if (IsHttp10)
{
if (responseCode < 400 && "keep-alive".Equals(GetRequestHeader("connection"), StringComparison.OrdinalIgnoreCase))
{
keepAlive = true;
Buffer.BlockCopy(ConnectionKeepAlive, 0, OutputTemp, offset, ConnectionKeepAlive.Length);
offset += ConnectionKeepAlive.Length;
}
else
{
keepAlive = false;
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, false);
Buffer.BlockCopy(ConnectionClose, 0, OutputTemp, offset, ConnectionClose.Length);
offset += ConnectionClose.Length;
}
}
else
{
if (responseCode >= 400 || "close".Equals(GetRequestHeader("connection"), StringComparison.OrdinalIgnoreCase))
{
keepAlive = false;
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, false);
Buffer.BlockCopy(ConnectionClose, 0, OutputTemp, offset, ConnectionClose.Length);
offset += ConnectionClose.Length;
}
else keepAlive = true;
}
offset = AddServerAndDate(offset);
var cms = stream as ChunkedMemoryStream;
var mustFlushResponse = forceFlush || !keepAlive || !Pipeline;
if (cms != null)
{
offset = AddContentLength(cms.Length, offset);
var len = offset + cms.Length;
if (len < 4096)
{
cms.CopyTo(OutputTemp, offset);
if (mustFlushResponse || len > 1024)
{
offsetInOutput = 0;
socket.Send(OutputTemp, (int)len, SocketFlags.None);
}
else offsetInOutput = (int)len;
}
else
{
socket.Send(OutputTemp, offset, SocketFlags.Partial);
cms.Send(socket);
offsetInOutput = 0;
}
cms.Dispose();
}
else if (stream != null)
{
try
{
long len;
if (ResponseLength != null)
len = ResponseLength.Value;
else if (stream.CanSeek)
len = stream.Length;
else
throw new NotSupportedException("Chunked stream not implemented");
offset = AddContentLength(len, offset);
if (len + offset < OutputTemp.Length)
{
int pos = 0;
int size = (int)len;
do
{
pos += stream.Read(OutputTemp, pos + offset, size - pos);
} while (pos < len);
offset += size;
if (mustFlushResponse)
{
socket.Send(OutputTemp, offset, SocketFlags.None);
offsetInOutput = 0;
}
else offsetInOutput = offset;
}
else
{
int pos = 0;
int size = (int)len;
socket.Send(OutputTemp, offset, SocketFlags.Partial);
do
{
pos = stream.Read(OutputTemp, 0, OutputTemp.Length);
socket.Send(OutputTemp, pos, SocketFlags.None);
} while (pos != 0);
offsetInOutput = 0;
}
}
finally
{
stream.Dispose();
}
}
else
{
Buffer.BlockCopy(ZeroContentLength, 0, OutputTemp, offset, ZeroContentLength.Length);
offset += ZeroContentLength.Length;
if (mustFlushResponse)
{
socket.Send(OutputTemp, offset, SocketFlags.None);
offsetInOutput = 0;
}
else offsetInOutput = offset;
}
return keepAlive;
}