diff --git a/SocketHttpListener/Net/ChunkStream.cs b/SocketHttpListener/Net/ChunkStream.cs index 2de6c2c182..b41285dbca 100644 --- a/SocketHttpListener/Net/ChunkStream.cs +++ b/SocketHttpListener/Net/ChunkStream.cs @@ -79,12 +79,6 @@ namespace SocketHttpListener.Net private int _trailerState; private List _chunks; - public ChunkStream(byte[] buffer, int offset, int size, WebHeaderCollection headers) - : this(headers) - { - Write(buffer, offset, size); - } - public ChunkStream(WebHeaderCollection headers) { _headers = headers; @@ -102,13 +96,6 @@ namespace SocketHttpListener.Net _chunks.Clear(); } - public void WriteAndReadBack(byte[] buffer, int offset, int size, ref int read) - { - if (offset + read > 0) - Write(buffer, offset, offset + read); - read = Read(buffer, offset, size); - } - public int Read(byte[] buffer, int offset, int size) { return ReadFromChunks(buffer, offset, size); @@ -143,6 +130,9 @@ namespace SocketHttpListener.Net public void Write(byte[] buffer, int offset, int size) { + // Note, the logic here only works when offset is 0 here. + // Otherwise, it would treat "size" as the end offset instead of an actual byte count from offset. + if (offset < size) InternalWrite(buffer, ref offset, size); } diff --git a/SocketHttpListener/Net/ChunkedInputStream.cs b/SocketHttpListener/Net/ChunkedInputStream.cs index 2e0e1964be..919bd95ea0 100644 --- a/SocketHttpListener/Net/ChunkedInputStream.cs +++ b/SocketHttpListener/Net/ChunkedInputStream.cs @@ -122,11 +122,19 @@ namespace SocketHttpListener.Net try { int nread = base.EndRead(base_ares); + if (nread == 0) + { + _no_more_data = true; + ares._count = rb.InitialCount - rb.Count; + ares.Complete(); + return; + } + _decoder.Write(ares._buffer, ares._offset, nread); nread = _decoder.Read(rb.Buffer, rb.Offset, rb.Count); rb.Offset += nread; rb.Count -= nread; - if (rb.Count == 0 || !_decoder.WantMore || nread == 0) + if (rb.Count == 0 || !_decoder.WantMore) { _no_more_data = !_decoder.WantMore && nread == 0; ares._count = rb.InitialCount - rb.Count; @@ -164,7 +172,7 @@ namespace SocketHttpListener.Net asyncResult.AsyncWaitHandle.WaitOne(); if (ares._error != null) - throw new HttpListenerException((int)HttpStatusCode.BadRequest, "Bad Request"); + throw new HttpListenerException((int)HttpStatusCode.BadRequest, "Operation aborted"); return ares._count; } diff --git a/SocketHttpListener/Net/HttpConnection.cs b/SocketHttpListener/Net/HttpConnection.cs index 79491d6f9c..e66443c590 100644 --- a/SocketHttpListener/Net/HttpConnection.cs +++ b/SocketHttpListener/Net/HttpConnection.cs @@ -268,7 +268,8 @@ namespace SocketHttpListener.Net if (!_epl.BindContext(_context)) { - SendError("Invalid host", 400); + const int NotFoundErrorCode = 404; + SendError(HttpStatusDescription.Get(NotFoundErrorCode), NotFoundErrorCode); Close(true); return; } diff --git a/SocketHttpListener/Net/HttpListenerRequest.cs b/SocketHttpListener/Net/HttpListenerRequest.cs index 6a99eb0786..f9df525934 100644 --- a/SocketHttpListener/Net/HttpListenerRequest.cs +++ b/SocketHttpListener/Net/HttpListenerRequest.cs @@ -31,7 +31,7 @@ namespace SocketHttpListener.Net HttpListenerContext context; bool is_chunked; bool ka_set; - bool keep_alive; + bool? _keepAlive; private readonly ITextEncoding _textEncoding; @@ -525,29 +525,35 @@ namespace SocketHttpListener.Net { get { - if (ka_set) - return keep_alive; - - ka_set = true; - // 1. Connection header - // 2. Protocol (1.1 == keep-alive by default) - // 3. Keep-Alive header - string cnc = headers["Connection"]; - if (!String.IsNullOrEmpty(cnc)) + if (!_keepAlive.HasValue) { - keep_alive = (0 == String.Compare(cnc, "keep-alive", StringComparison.OrdinalIgnoreCase)); - } - else if (version == HttpVersion.Version11) - { - keep_alive = true; - } - else - { - cnc = headers["keep-alive"]; - if (!String.IsNullOrEmpty(cnc)) - keep_alive = (0 != String.Compare(cnc, "closed", StringComparison.OrdinalIgnoreCase)); + string header = Headers["Proxy-Connection"]; + if (string.IsNullOrEmpty(header)) + { + header = Headers["Connection"]; + } + if (string.IsNullOrEmpty(header)) + { + if (ProtocolVersion >= HttpVersion.Version11) + { + _keepAlive = true; + } + else + { + header = Headers["Keep-Alive"]; + _keepAlive = !string.IsNullOrEmpty(header); + } + } + else + { + header = header.ToLower(CultureInfo.InvariantCulture); + _keepAlive = + header.IndexOf("close", StringComparison.OrdinalIgnoreCase) < 0 || + header.IndexOf("keep-alive", StringComparison.OrdinalIgnoreCase) >= 0; + } } - return keep_alive; + + return _keepAlive.Value; } } diff --git a/SocketHttpListener/Net/HttpStreamAsyncResult.cs b/SocketHttpListener/Net/HttpStreamAsyncResult.cs index e7e516c6b4..d96988fcef 100644 --- a/SocketHttpListener/Net/HttpStreamAsyncResult.cs +++ b/SocketHttpListener/Net/HttpStreamAsyncResult.cs @@ -66,10 +66,7 @@ namespace SocketHttpListener.Net } } - public bool CompletedSynchronously - { - get { return (_synchRead == _count); } - } + public bool CompletedSynchronously => false; public bool IsCompleted { diff --git a/SocketHttpListener/Net/UriScheme.cs b/SocketHttpListener/Net/UriScheme.cs new file mode 100644 index 0000000000..eb13619c9d --- /dev/null +++ b/SocketHttpListener/Net/UriScheme.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SocketHttpListener.Net +{ + internal class UriScheme + { + public const string File = "file"; + public const string Ftp = "ftp"; + public const string Gopher = "gopher"; + public const string Http = "http"; + public const string Https = "https"; + public const string News = "news"; + public const string NetPipe = "net.pipe"; + public const string NetTcp = "net.tcp"; + public const string Nntp = "nntp"; + public const string Mailto = "mailto"; + public const string Ws = "ws"; + public const string Wss = "wss"; + + public const string SchemeDelimiter = "://"; + } +} diff --git a/SocketHttpListener/SocketHttpListener.csproj b/SocketHttpListener/SocketHttpListener.csproj index 9cdc953c51..1aa7889316 100644 --- a/SocketHttpListener/SocketHttpListener.csproj +++ b/SocketHttpListener/SocketHttpListener.csproj @@ -82,6 +82,7 @@ +