update response stream
This commit is contained in:
parent
799494af0b
commit
ff9ad62c9c
|
@ -76,40 +76,43 @@ namespace SocketHttpListener.Net
|
||||||
if (disposed == false)
|
if (disposed == false)
|
||||||
{
|
{
|
||||||
disposed = true;
|
disposed = true;
|
||||||
byte[] bytes = null;
|
using (var ms = GetHeaders(response, _memoryStreamFactory, false))
|
||||||
MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false);
|
|
||||||
bool chunked = response.SendChunked;
|
|
||||||
if (stream.CanWrite)
|
|
||||||
{
|
{
|
||||||
try
|
if (stream.CanWrite)
|
||||||
{
|
{
|
||||||
if (ms != null)
|
try
|
||||||
{
|
{
|
||||||
long start = ms.Position;
|
bool chunked = response.SendChunked;
|
||||||
if (chunked && !trailer_sent)
|
|
||||||
|
if (ms != null)
|
||||||
{
|
{
|
||||||
bytes = GetChunkSizeBytes(0, true);
|
var start = ms.Position;
|
||||||
ms.Position = ms.Length;
|
if (chunked && !trailer_sent)
|
||||||
ms.Write(bytes, 0, bytes.Length);
|
{
|
||||||
|
trailer_sent = true;
|
||||||
|
var bytes = GetChunkSizeBytes(0, true);
|
||||||
|
ms.Position = ms.Length;
|
||||||
|
ms.Write(bytes, 0, bytes.Length);
|
||||||
|
ms.Position = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms.CopyTo(stream);
|
||||||
|
}
|
||||||
|
else if (chunked && !trailer_sent)
|
||||||
|
{
|
||||||
|
trailer_sent = true;
|
||||||
|
|
||||||
|
var bytes = GetChunkSizeBytes(0, true);
|
||||||
|
stream.Write(bytes, 0, bytes.Length);
|
||||||
}
|
}
|
||||||
byte[] msBuffer;
|
|
||||||
_memoryStreamFactory.TryGetBuffer(ms, out msBuffer);
|
|
||||||
InternalWrite(msBuffer, (int)start, (int)(ms.Length - start));
|
|
||||||
trailer_sent = true;
|
|
||||||
}
|
}
|
||||||
else if (chunked && !trailer_sent)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
bytes = GetChunkSizeBytes(0, true);
|
// Ignore error due to connection reset by peer
|
||||||
InternalWrite(bytes, 0, bytes.Length);
|
|
||||||
trailer_sent = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
response.Close();
|
||||||
{
|
|
||||||
// Ignore error due to connection reset by peer
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
response.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
|
@ -122,7 +125,7 @@ namespace SocketHttpListener.Net
|
||||||
{
|
{
|
||||||
if (response.HeadersSent)
|
if (response.HeadersSent)
|
||||||
return null;
|
return null;
|
||||||
MemoryStream ms = memoryStreamFactory.CreateNew();
|
var ms = memoryStreamFactory.CreateNew();
|
||||||
response.SendHeaders(closing, ms);
|
response.SendHeaders(closing, ms);
|
||||||
return ms;
|
return ms;
|
||||||
}
|
}
|
||||||
|
@ -144,6 +147,7 @@ namespace SocketHttpListener.Net
|
||||||
stream.Write(buffer, offset, count);
|
stream.Write(buffer, offset, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int MsCopyBufferSize = 81920;
|
||||||
public override void Write(byte[] buffer, int offset, int count)
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
{
|
{
|
||||||
if (disposed)
|
if (disposed)
|
||||||
|
@ -151,42 +155,46 @@ namespace SocketHttpListener.Net
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
{
|
{
|
||||||
//return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] bytes = null;
|
using (var ms = GetHeaders(response, _memoryStreamFactory, false))
|
||||||
MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false);
|
|
||||||
bool chunked = response.SendChunked;
|
|
||||||
if (ms != null)
|
|
||||||
{
|
{
|
||||||
long start = ms.Position; // After the possible preamble for the encoding
|
bool chunked = response.SendChunked;
|
||||||
ms.Position = ms.Length;
|
if (ms != null)
|
||||||
if (chunked)
|
|
||||||
{
|
{
|
||||||
bytes = GetChunkSizeBytes(count, false);
|
long start = ms.Position; // After the possible preamble for the encoding
|
||||||
ms.Write(bytes, 0, bytes.Length);
|
ms.Position = ms.Length;
|
||||||
|
if (chunked)
|
||||||
|
{
|
||||||
|
var bytes = GetChunkSizeBytes(count, false);
|
||||||
|
ms.Write(bytes, 0, bytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
ms.Write(buffer, offset, count);
|
||||||
|
|
||||||
|
if (chunked)
|
||||||
|
{
|
||||||
|
ms.Write(crlf, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
ms.Position = start;
|
||||||
|
ms.CopyTo(stream, MsCopyBufferSize);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int new_count = Math.Min(count, 16384 - (int)ms.Position + (int)start);
|
if (chunked)
|
||||||
ms.Write(buffer, offset, new_count);
|
{
|
||||||
count -= new_count;
|
var bytes = GetChunkSizeBytes(count, false);
|
||||||
offset += new_count;
|
stream.Write(bytes, 0, bytes.Length);
|
||||||
byte[] msBuffer;
|
}
|
||||||
_memoryStreamFactory.TryGetBuffer(ms, out msBuffer);
|
|
||||||
InternalWrite(msBuffer, (int)start, (int)(ms.Length - start));
|
|
||||||
ms.SetLength(0);
|
|
||||||
ms.Capacity = 0; // 'dispose' the buffer in ms.
|
|
||||||
}
|
|
||||||
else if (chunked)
|
|
||||||
{
|
|
||||||
bytes = GetChunkSizeBytes(count, false);
|
|
||||||
InternalWrite(bytes, 0, bytes.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count > 0)
|
stream.Write(buffer, offset, count);
|
||||||
InternalWrite(buffer, offset, count);
|
|
||||||
if (chunked)
|
if (chunked)
|
||||||
InternalWrite(crlf, 0, 2);
|
stream.Write(crlf, 0, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||||
|
@ -196,113 +204,53 @@ namespace SocketHttpListener.Net
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
{
|
{
|
||||||
//return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] bytes = null;
|
using (var ms = GetHeaders(response, _memoryStreamFactory, false))
|
||||||
MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false);
|
|
||||||
bool chunked = response.SendChunked;
|
|
||||||
if (ms != null)
|
|
||||||
{
|
{
|
||||||
long start = ms.Position;
|
bool chunked = response.SendChunked;
|
||||||
ms.Position = ms.Length;
|
if (ms != null)
|
||||||
|
{
|
||||||
|
long start = ms.Position; // After the possible preamble for the encoding
|
||||||
|
ms.Position = ms.Length;
|
||||||
|
if (chunked)
|
||||||
|
{
|
||||||
|
var bytes = GetChunkSizeBytes(count, false);
|
||||||
|
ms.Write(bytes, 0, bytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
ms.Write(buffer, offset, count);
|
||||||
|
|
||||||
|
if (chunked)
|
||||||
|
{
|
||||||
|
ms.Write(crlf, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
ms.Position = start;
|
||||||
|
await ms.CopyToAsync(stream, MsCopyBufferSize, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (chunked)
|
if (chunked)
|
||||||
{
|
{
|
||||||
bytes = GetChunkSizeBytes(count, false);
|
var bytes = GetChunkSizeBytes(count, false);
|
||||||
ms.Write(bytes, 0, bytes.Length);
|
stream.Write(bytes, 0, bytes.Length);
|
||||||
}
|
}
|
||||||
ms.Write(buffer, offset, count);
|
|
||||||
byte[] msBuffer;
|
|
||||||
_memoryStreamFactory.TryGetBuffer(ms, out msBuffer);
|
|
||||||
buffer = msBuffer;
|
|
||||||
offset = (int)start;
|
|
||||||
count = (int)(ms.Position - start);
|
|
||||||
}
|
|
||||||
else if (chunked)
|
|
||||||
{
|
|
||||||
bytes = GetChunkSizeBytes(count, false);
|
|
||||||
InternalWrite(bytes, 0, bytes.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count > 0)
|
|
||||||
{
|
|
||||||
await stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
|
await stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (chunked)
|
||||||
|
stream.Write(crlf, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunked)
|
|
||||||
stream.Write(crlf, 0, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count,
|
|
||||||
// AsyncCallback cback, object state)
|
|
||||||
//{
|
|
||||||
// if (disposed)
|
|
||||||
// throw new ObjectDisposedException(GetType().ToString());
|
|
||||||
|
|
||||||
// byte[] bytes = null;
|
|
||||||
// MemoryStream ms = GetHeaders(false);
|
|
||||||
// bool chunked = response.SendChunked;
|
|
||||||
// if (ms != null)
|
|
||||||
// {
|
|
||||||
// long start = ms.Position;
|
|
||||||
// ms.Position = ms.Length;
|
|
||||||
// if (chunked)
|
|
||||||
// {
|
|
||||||
// bytes = GetChunkSizeBytes(count, false);
|
|
||||||
// ms.Write(bytes, 0, bytes.Length);
|
|
||||||
// }
|
|
||||||
// ms.Write(buffer, offset, count);
|
|
||||||
// buffer = ms.ToArray();
|
|
||||||
// offset = (int)start;
|
|
||||||
// count = (int)(ms.Position - start);
|
|
||||||
// }
|
|
||||||
// else if (chunked)
|
|
||||||
// {
|
|
||||||
// bytes = GetChunkSizeBytes(count, false);
|
|
||||||
// InternalWrite(bytes, 0, bytes.Length);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return stream.BeginWrite(buffer, offset, count, cback, state);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//public override void EndWrite(IAsyncResult ares)
|
|
||||||
//{
|
|
||||||
// if (disposed)
|
|
||||||
// throw new ObjectDisposedException(GetType().ToString());
|
|
||||||
|
|
||||||
// if (ignore_errors)
|
|
||||||
// {
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// stream.EndWrite(ares);
|
|
||||||
// if (response.SendChunked)
|
|
||||||
// stream.Write(crlf, 0, 2);
|
|
||||||
// }
|
|
||||||
// catch { }
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// stream.EndWrite(ares);
|
|
||||||
// if (response.SendChunked)
|
|
||||||
// stream.Write(crlf, 0, 2);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
public override int Read([In, Out] byte[] buffer, int offset, int count)
|
public override int Read([In, Out] byte[] buffer, int offset, int count)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
//public override IAsyncResult BeginRead(byte[] buffer, int offset, int count,
|
|
||||||
// AsyncCallback cback, object state)
|
|
||||||
//{
|
|
||||||
// throw new NotSupportedException();
|
|
||||||
//}
|
|
||||||
|
|
||||||
//public override int EndRead(IAsyncResult ares)
|
|
||||||
//{
|
|
||||||
// throw new NotSupportedException();
|
|
||||||
//}
|
|
||||||
|
|
||||||
public override long Seek(long offset, SeekOrigin origin)
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
|
@ -313,27 +261,35 @@ namespace SocketHttpListener.Net
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool EnableSendFileWithSocket
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
public Task TransmitFile(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
|
public Task TransmitFile(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
//if (_supportsDirectSocketAccess && offset == 0 && count == 0 && !response.SendChunked && response.ContentLength64 > 8192)
|
if (_supportsDirectSocketAccess && offset == 0 && count == 0 && !response.SendChunked && response.ContentLength64 > 8192)
|
||||||
//{
|
{
|
||||||
// return TransmitFileOverSocket(path, offset, count, fileShareMode, cancellationToken);
|
if (EnableSendFileWithSocket)
|
||||||
//}
|
{
|
||||||
|
return TransmitFileOverSocket(path, offset, count, fileShareMode, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
return TransmitFileManaged(path, offset, count, fileShareMode, cancellationToken);
|
return TransmitFileManaged(path, offset, count, fileShareMode, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly byte[] _emptyBuffer = new byte[] { };
|
private readonly byte[] _emptyBuffer = new byte[] { };
|
||||||
private Task TransmitFileOverSocket(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
|
private Task TransmitFileOverSocket(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false);
|
var ms = GetHeaders(response, _memoryStreamFactory, false);
|
||||||
|
|
||||||
byte[] buffer;
|
byte[] preBuffer;
|
||||||
if (ms != null)
|
if (ms != null)
|
||||||
{
|
{
|
||||||
using (var msCopy = new MemoryStream())
|
using (var msCopy = new MemoryStream())
|
||||||
{
|
{
|
||||||
ms.CopyTo(msCopy);
|
ms.CopyTo(msCopy);
|
||||||
buffer = msCopy.ToArray();
|
preBuffer = msCopy.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -342,7 +298,7 @@ namespace SocketHttpListener.Net
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Info("Socket sending file {0} {1}", path, response.ContentLength64);
|
_logger.Info("Socket sending file {0} {1}", path, response.ContentLength64);
|
||||||
return _socket.SendFile(path, buffer, _emptyBuffer, cancellationToken);
|
return _socket.SendFile(path, preBuffer, _emptyBuffer, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task TransmitFileManaged(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
|
private async Task TransmitFileManaged(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user