From 6905216ebce17f65f06f2cf44c820e521c40c826 Mon Sep 17 00:00:00 2001 From: Geo Perez Date: Mon, 27 Feb 2017 11:21:50 -0600 Subject: [PATCH] Releasing tag 1.5.0 --- .../System.Net/ChunkStream.cs | 13 +- .../System.Net/ChunkedInputStream.cs | 7 +- .../System.Net/HttpConnection.cs | 6 + .../System.Net/HttpListenerException.cs | 1 - .../System.Net/HttpListenerRequest.cs | 51 +------ .../System.Net/HttpStreamAsyncResult.cs | 4 +- .../System.Net/NetExtensions.cs | 143 ++---------------- .../System.Net/PayloadData.cs | 7 +- .../System.Net/RequestStream.cs | 2 + .../System.Net/WebHeaderCollection.cs | 20 ++- .../System.Net/WebSocket.cs | 28 +++- .../System.Net/WebSocketFrame.cs | 23 ++- src/Unosquare.Labs.EmbedIO/project.json | 2 +- .../StaticFilesModuleTest.cs | 36 +++-- .../Unosquare.Labs.EmbedIO.Tests/project.json | 4 +- 15 files changed, 134 insertions(+), 213 deletions(-) diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/ChunkStream.cs b/src/Unosquare.Labs.EmbedIO/System.Net/ChunkStream.cs index 4209509ec..72c7a6c09 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/ChunkStream.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/ChunkStream.cs @@ -1,4 +1,5 @@ -#if !NET46 +#if CHUNKED +#if !NET46 // // System.Net.ChunkStream // @@ -376,7 +377,7 @@ private State ReadTrailer(byte[] buffer, ref int offset, int size) var reader = new StringReader(_saved.ToString()); string line; while ((line = reader.ReadLine()) != null && line != "") - Headers.Add(line); + AddHeader(line); return State.None; } @@ -386,6 +387,14 @@ private static void ThrowProtocolViolation(string message) var we = new System.Net.WebException(message, null, System.Net.WebExceptionStatus.ServerProtocolViolation, null); throw we; } + + internal void AddHeader(string data) + { + var set = data.Split(':'); + if (set.Length == 2) + Headers[set[0].Trim()] = set[1].Trim(); + } } } +#endif #endif \ No newline at end of file diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/ChunkedInputStream.cs b/src/Unosquare.Labs.EmbedIO/System.Net/ChunkedInputStream.cs index 65607ebed..476c24cbb 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/ChunkedInputStream.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/ChunkedInputStream.cs @@ -1,4 +1,5 @@ -#if !NET46 +#if CHUNKED +#if !NET46 // // System.Net.ChunkedInputStream // @@ -35,7 +36,6 @@ namespace Unosquare.Net internal class ChunkedInputStream : RequestStream { private bool _disposed; - private readonly HttpListenerContext _context; private bool _noMoreData; private class ReadBufferState @@ -61,7 +61,6 @@ public ChunkedInputStream(HttpListenerContext context, Stream stream, byte[] buffer, int offset, int length) : base(stream, buffer, offset, length) { - _context = context; Decoder = new ChunkStream(context.Request.Headers); } @@ -186,5 +185,5 @@ public void Close() } } } - +#endif #endif \ No newline at end of file diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/HttpConnection.cs b/src/Unosquare.Labs.EmbedIO/System.Net/HttpConnection.cs index 10a476da2..e3e139fad 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/HttpConnection.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/HttpConnection.cs @@ -179,16 +179,22 @@ public RequestStream GetRequestStream(bool chunked, long contentlength) var buffer = _ms.ToArray(); var length = (int) _ms.Length; _ms = null; + if (chunked) { +#if CHUNKED _chunked = true; _context.Response.SendChunked = true; _iStream = new ChunkedInputStream(_context, Stream, buffer, _position, length - _position); +#else + throw new InvalidOperationException("Chunked transfer encoding is not supported"); +#endif } else { _iStream = new RequestStream(Stream, buffer, _position, length - _position, contentlength); } + return _iStream; } diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerException.cs b/src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerException.cs index 2930e77a5..cfca7837c 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerException.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerException.cs @@ -1,5 +1,4 @@ #if !NET46 -using System; using System.ComponentModel; using System.Runtime.InteropServices; diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerRequest.cs b/src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerRequest.cs index d09683594..1053283e5 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerRequest.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerRequest.cs @@ -82,7 +82,7 @@ public override ChannelBinding GetChannelBinding(ChannelBindingKind kind) private bool _isChunked; private bool _kaSet; private bool _keepAlive; - + #if SSL delegate X509Certificate2 GccDelegate(); GccDelegate _gccDelegate; @@ -254,6 +254,7 @@ internal void FinishInitialization() _url = HttpListenerRequestUriBuilder.GetRequestUri(RawUrl, _url.Scheme, _url.Authority, _url.LocalPath, _url.Query); +#if CHUNKED if (ProtocolVersion >= HttpVersion.Version11) { var tEncoding = Headers["Transfer-Encoding"]; @@ -264,6 +265,7 @@ internal void FinishInitialization() return; } } +#endif if (!_isChunked && !_clSet) { @@ -280,7 +282,7 @@ internal void FinishInitialization() output.InternalWrite(_100Continue, 0, _100Continue.Length); } } - + internal void AddHeader(string header) { var colon = header.IndexOf(':'); @@ -295,6 +297,7 @@ internal void AddHeader(string header) var val = header.Substring(colon + 1).Trim(); var lower = name.ToLowerInvariant(); Headers.Set(name, val); + switch (lower) { case "accept-language": @@ -429,7 +432,7 @@ internal bool FlushInput() /// The accept types. /// public string[] AcceptTypes { get; private set; } - + #if SSL /// /// Gets the client certificate error code. @@ -496,25 +499,16 @@ public int ClientCertificateError /// /// Gets the request headers. /// - /// - /// The headers. - /// public NameValueCollection Headers { get; } /// /// Gets the HTTP method. /// - /// - /// The HTTP method. - /// public string HttpMethod { get; private set; } /// /// Gets the input stream. /// - /// - /// The input stream. - /// public Stream InputStream { get @@ -534,33 +528,21 @@ public Stream InputStream /// /// Gets a value indicating whether this request is authenticated. /// - /// - /// true if this instance is authenticated; otherwise, false. - /// public bool IsAuthenticated => false; /// /// Gets a value indicating whether this request is local. /// - /// - /// true if this instance is local; otherwise, false. - /// public bool IsLocal => LocalEndPoint.Address.Equals(RemoteEndPoint.Address); /// /// Gets a value indicating whether this request is under a secure connection. /// - /// - /// true if this instance is secure connection; otherwise, false. - /// public bool IsSecureConnection => _context.Connection.IsSecure; /// /// Gets the Keep-Alive value for this request /// - /// - /// true if [keep alive]; otherwise, false. - /// public bool KeepAlive { get @@ -594,57 +576,36 @@ public bool KeepAlive /// /// Gets the local end point. /// - /// - /// The local end point. - /// public IPEndPoint LocalEndPoint => _context.Connection.LocalEndPoint; /// /// Gets the protocol version. /// - /// - /// The protocol version. - /// public Version ProtocolVersion { get; private set; } /// /// Gets the query string. /// - /// - /// The query string. - /// public NameValueCollection QueryString { get; private set; } /// /// Gets the raw URL. /// - /// - /// The raw URL. - /// public string RawUrl { get; private set; } /// /// Gets the remote end point. /// - /// - /// The remote end point. - /// public IPEndPoint RemoteEndPoint => _context.Connection.RemoteEndPoint; /// /// Gets the request trace identifier. /// - /// - /// The request trace identifier. - /// public Guid RequestTraceIdentifier => Guid.Empty; /// /// Gets the URL. /// - /// - /// The URL. - /// public Uri Url => _url; /// diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/HttpStreamAsyncResult.cs b/src/Unosquare.Labs.EmbedIO/System.Net/HttpStreamAsyncResult.cs index 0f735a190..9e5a9a6e3 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/HttpStreamAsyncResult.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/HttpStreamAsyncResult.cs @@ -1,4 +1,5 @@ -#if !NET46 +#if CHUNKED +#if !NET46 // // System.Net.HttpStreamAsyncResult // @@ -96,4 +97,5 @@ public bool IsCompleted } } } +#endif #endif \ No newline at end of file diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/NetExtensions.cs b/src/Unosquare.Labs.EmbedIO/System.Net/NetExtensions.cs index eba11410e..564d3eed3 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/NetExtensions.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/NetExtensions.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.IO; -using System.IO.Compression; using System.Linq; using System.Text; using System; @@ -17,7 +16,7 @@ namespace Unosquare.Net /// Represents an asynchronous operation result. /// /// - public class AsyncResult : IAsyncResult + internal class AsyncResult : IAsyncResult { /// /// Initializes a new instance of the class. @@ -201,31 +200,7 @@ public static int EndRead(this Stream stream, IAsyncResult ares) var result = (AsyncResult)ares; return (int)result.Data; } - - /// - /// Parses and adds the data from a string into the specified Name-Value collection - /// - /// The coll. - /// The data. - public static void Add(this NameValueCollection coll, string data) - { - var set = data.Split(':'); - if (set.Length == 2) - coll[set[0].Trim()] = set[1].Trim(); - } - - /// - /// Parses and adds the data from a string into the specified Name-Value collection - /// - /// The coll. - /// The data. - public static void Add(this WebHeaderCollection coll, string data) - { - var set = data.Split(':'); - if (set.Length == 2) - coll[set[0].Trim()] = set[1].Trim(); - } - + /// /// The scheme delimiter /// @@ -277,7 +252,7 @@ public UriScheme(string s, string d, int p) } }; - static readonly UriScheme[] _schemes = { + private static readonly UriScheme[] Schemes = { new UriScheme (UriSchemeHttp, SchemeDelimiter, 80), new UriScheme (UriSchemeHttps, SchemeDelimiter, 443), new UriScheme (UriSchemeFtp, SchemeDelimiter, 21), @@ -290,17 +265,17 @@ public UriScheme(string s, string d, int p) internal static string GetSchemeDelimiter(string scheme) { - for (var i = 0; i < _schemes.Length; i++) - if (_schemes[i].Scheme == scheme) - return _schemes[i].Delimiter; + for (var i = 0; i < Schemes.Length; i++) + if (Schemes[i].Scheme == scheme) + return Schemes[i].Delimiter; return SchemeDelimiter; } internal static int GetDefaultPort(string scheme) { - for (var i = 0; i < _schemes.Length; i++) - if (_schemes[i].Scheme == scheme) - return _schemes[i].DefaultPort; + for (var i = 0; i < Schemes.Length; i++) + if (Schemes[i].Scheme == scheme) + return Schemes[i].DefaultPort; return -1; } @@ -552,13 +527,7 @@ internal static byte[] ReadBytes(this Stream stream, long length, int bufferLeng return dest.ToArray(); } } - - internal static void WriteBytes(this Stream stream, byte[] bytes, int bufferLength) - { - using (var input = new MemoryStream(bytes)) - input.CopyTo(stream, bufferLength); - } - + internal static byte[] ReadBytes(this Stream stream, int length) { var buff = new byte[length]; @@ -714,25 +683,7 @@ Action error error?.Invoke(ex); } } - - internal static bool IsSupported(this byte opcode) - { - return Enum.IsDefined(typeof(Opcode), opcode); - } - - internal static ulong ToUInt64(this byte[] source, Endianness sourceOrder) - { - return BitConverter.ToUInt64(source.ToHostOrder(sourceOrder), 0); - } - internal static bool IsReserved(this ushort code) - { - return code == (ushort)CloseStatusCode.Undefined || - code == (ushort)CloseStatusCode.NoStatus || - code == (ushort)CloseStatusCode.Abnormal || - code == (ushort)CloseStatusCode.TlsHandshakeFailure; - } - internal static bool IsReserved(this CloseStatusCode code) { return code == CloseStatusCode.Undefined || @@ -740,12 +691,7 @@ internal static bool IsReserved(this CloseStatusCode code) code == CloseStatusCode.Abnormal || code == CloseStatusCode.TlsHandshakeFailure; } - - internal static ushort ToUInt16(this byte[] source, Endianness sourceOrder) - { - return BitConverter.ToUInt16(source.ToHostOrder(sourceOrder), 0); - } - + /// /// Converts the order of the specified array of to the host byte order. /// @@ -780,7 +726,7 @@ public static byte[] ToHostOrder(this byte[] source, Endianness sourceOrder) /// /// One of the enum values, to test. /// - public static bool IsHostOrder(this Endianness order) + internal static bool IsHostOrder(this Endianness order) { // true: !(true ^ true) or !(false ^ false) // false: !(true ^ false) or !(false ^ true) @@ -932,35 +878,7 @@ internal static bool IsToken(this string value) { return value.All(c => c >= 0x20 && c < 0x7f && !Tspecials.Contains(c)); } - - internal static bool ContainsTwice(string[] values) - { - var len = values.Length; - - Func contains = null; - contains = idx => - { - if (idx >= len - 1) return false; - - for (var i = idx + 1; i < len; i++) - if (values[i] == values[idx]) - return true; - - return contains(++idx); - }; - - return contains(0); - } - - internal static string CheckIfValidProtocols(this string[] protocols) - { - return protocols.Any(protocol => string.IsNullOrEmpty(protocol) || !protocol.IsToken()) - ? "Contains an invalid value." - : ContainsTwice(protocols) - ? "Contains a value twice." - : null; - } - + /// /// Gets the collection of the HTTP cookies from the specified HTTP . /// @@ -982,16 +900,6 @@ public static CookieCollection GetCookies(this NameValueCollection headers, bool : new CookieCollection(); } - internal static bool CheckWaitTime(this TimeSpan time, out string message) - { - message = null; - - if (time > TimeSpan.Zero) return true; - - message = "A wait time is zero or less."; - return false; - } - internal static string ToExtensionString(this CompressionMethod method, params string[] parameters) { if (method == CompressionMethod.None) @@ -1004,30 +912,7 @@ internal static string ToExtensionString(this CompressionMethod method, params s return $"{m}; {string.Join("; ", parameters)}"; } - - internal static bool IsText(this string value) - { - var len = value.Length; - for (var i = 0; i < len; i++) - { - var c = value[i]; - if (c < 0x20 && !"\r\n\t".Contains(c)) - return false; - - if (c == 0x7f) - return false; - - if (c == '\n' && ++i < len) - { - c = value[i]; - if (!" \t".Contains(c)) - return false; - } - } - - return true; - } - + /// /// Determines whether the specified contains the entry with /// the specified both and . diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/PayloadData.cs b/src/Unosquare.Labs.EmbedIO/System.Net/PayloadData.cs index 91d4c8895..3cfaa5178 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/PayloadData.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/PayloadData.cs @@ -122,7 +122,7 @@ internal ushort Code if (!_codeSet) { _code = _length > 1 - ? _data.SubArray(0, 2).ToUInt16(Swan.Endianness.Big) + ? BitConverter.ToUInt16(_data.SubArray(0, 2).ToHostOrder(Swan.Endianness.Big), 0) : (ushort)1005; _codeSet = true; @@ -134,7 +134,10 @@ internal ushort Code internal long ExtensionDataLength { get; set; } - internal bool HasReservedCode => _length > 1 && Code.IsReserved(); + internal bool HasReservedCode => _length > 1 && (Code == (ushort)CloseStatusCode.Undefined || + Code == (ushort)CloseStatusCode.NoStatus || + Code == (ushort)CloseStatusCode.Abnormal || + Code == (ushort)CloseStatusCode.TlsHandshakeFailure); internal string Reason { diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/RequestStream.cs b/src/Unosquare.Labs.EmbedIO/System.Net/RequestStream.cs index dd7798e53..89c9cc497 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/RequestStream.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/RequestStream.cs @@ -143,6 +143,7 @@ public override int Read([In, Out] byte[] buffer, int offset, int count) return nread; } + #if CHUNKED #if !NETSTANDARD1_6 new #endif @@ -203,6 +204,7 @@ public int EndRead(IAsyncResult ares) _remainingBody -= nread; return nread; } +#endif public override long Seek(long offset, SeekOrigin origin) { diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/WebHeaderCollection.cs b/src/Unosquare.Labs.EmbedIO/System.Net/WebHeaderCollection.cs index 89d9af9b0..22cb77fa6 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/WebHeaderCollection.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/WebHeaderCollection.cs @@ -809,7 +809,25 @@ internal static bool IsHeaderName(string name) internal static bool IsHeaderValue(string value) { - return value.IsText(); + var len = value.Length; + for (var i = 0; i < len; i++) + { + var c = value[i]; + if (c < 0x20 && !"\r\n\t".Contains(c)) + return false; + + if (c == 0x7f) + return false; + + if (c == '\n' && ++i < len) + { + c = value[i]; + if (!" \t".Contains(c)) + return false; + } + } + + return true; } internal static bool IsMultiValue(string headerName, bool response) diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/WebSocket.cs b/src/Unosquare.Labs.EmbedIO/System.Net/WebSocket.cs index a8f9f6279..b5f7d9eaf 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/WebSocket.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/WebSocket.cs @@ -289,7 +289,8 @@ public WebSocket(string url, params string[] protocols) if (protocols != null && protocols.Length > 0) { - msg = protocols.CheckIfValidProtocols(); + msg = CheckIfValidProtocols(protocols); + if (msg != null) throw new ArgumentException(msg, nameof(protocols)); @@ -315,6 +316,15 @@ public WebSocket(string url, params string[] protocols) // As server internal Func CustomHandshakeRequestChecker { get; set; } + internal static string CheckIfValidProtocols(string[] protocols) + { + return protocols.Any(protocol => string.IsNullOrEmpty(protocol) || !protocol.IsToken()) + ? "Contains an invalid value." + : protocols.GroupBy(x => x).Select(x => new { x.Key, Count = x.Count() }).Any(x => x.Count > 1) + ? "Contains a value twice." + : null; + } + internal bool HasMessage { get @@ -597,7 +607,7 @@ public TimeSpan WaitTime { string msg; if (!checkIfAvailable(true, true, true, false, false, true, out msg) || - !value.CheckWaitTime(out msg)) + !CheckWaitTime(value, out msg)) { msg.Error(); Error("An error has occurred in setting the wait time.", null); @@ -638,6 +648,17 @@ public TimeSpan WaitTime #region Private Methods + internal static bool CheckWaitTime(TimeSpan time, out string message) + { + message = null; + + if (time > TimeSpan.Zero) return true; + + message = "A wait time is zero or less."; + return false; + } + + // As server private bool accept() { @@ -1387,7 +1408,8 @@ private bool ProcessFragmentFrame(WebSocketFrame frame) _inContinuation = true; } - _fragmentsBuffer.WriteBytes(frame.PayloadData.ApplicationData, 1024); + using (var input = new MemoryStream(frame.PayloadData.ApplicationData)) + input.CopyTo(_fragmentsBuffer, 1024); if (frame.IsFinal) { diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/WebSocketFrame.cs b/src/Unosquare.Labs.EmbedIO/System.Net/WebSocketFrame.cs index 259f02e8f..0cdf03af0 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/WebSocketFrame.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/WebSocketFrame.cs @@ -193,8 +193,8 @@ internal WebSocketFrame( internal ulong FullPayloadLength => PayloadLength < 126 ? PayloadLength : PayloadLength == 126 - ? ExtendedPayloadLength.ToUInt16(Swan.Endianness.Big) - : ExtendedPayloadLength.ToUInt64(Swan.Endianness.Big); + ? BitConverter.ToUInt16(ExtendedPayloadLength.ToHostOrder(Swan.Endianness.Big), 0) + : BitConverter.ToUInt64(ExtendedPayloadLength.ToHostOrder(Swan.Endianness.Big), 0); #endregion @@ -284,7 +284,7 @@ private static WebSocketFrame ProcessHeader(byte[] header) // Payload Length var payloadLen = (byte)(header[1] & 0x7f); - var err = !opcode.IsSupported() + var err = !Enum.IsDefined(typeof(Opcode), opcode) ? "An unsupported opcode." : !opcode.IsData() && rsv1 == Rsv.On ? "A non data frame is compressed." @@ -355,10 +355,7 @@ private static void ReadExtendedPayloadLengthAsync( error); } - private static WebSocketFrame ReadHeader(Stream stream) - { - return ProcessHeader(stream.ReadBytes(2)); - } + private static WebSocketFrame ReadHeader(Stream stream) => ProcessHeader(stream.ReadBytes(2)); private static void ReadHeaderAsync( Stream stream, Action completed, Action error) @@ -549,10 +546,7 @@ internal void Unmask() #region Public Methods - public IEnumerator GetEnumerator() - { - return ((IEnumerable) ToArray()).GetEnumerator(); - } + public IEnumerator GetEnumerator() => ((IEnumerable) ToArray()).GetEnumerator(); public string PrintToString() { @@ -610,9 +604,14 @@ public byte[] ToArray() { var bytes = PayloadData.ToArray(); if (PayloadLength < 127) + { buff.Write(bytes, 0, bytes.Length); + } else - buff.WriteBytes(bytes, 1024); + { + using (var input = new MemoryStream(bytes)) + input.CopyTo(buff, 1024); + } } #if NET452 diff --git a/src/Unosquare.Labs.EmbedIO/project.json b/src/Unosquare.Labs.EmbedIO/project.json index 3366a999f..83165863b 100644 --- a/src/Unosquare.Labs.EmbedIO/project.json +++ b/src/Unosquare.Labs.EmbedIO/project.json @@ -1,5 +1,5 @@ { - "version": "1.5.0-*", + "version": "1.5.1-*", "title": "Unosquare.Labs.EmbedIO", "description": "EmbedIO is a tiny, portable web server", "copyright": "Copyright © Unosquare 2013-2017", diff --git a/test/Unosquare.Labs.EmbedIO.Tests/StaticFilesModuleTest.cs b/test/Unosquare.Labs.EmbedIO.Tests/StaticFilesModuleTest.cs index 7b6a900e3..614b431c0 100644 --- a/test/Unosquare.Labs.EmbedIO.Tests/StaticFilesModuleTest.cs +++ b/test/Unosquare.Labs.EmbedIO.Tests/StaticFilesModuleTest.cs @@ -1,4 +1,6 @@ -namespace Unosquare.Labs.EmbedIO.Tests +using System.Net.Http.Headers; + +namespace Unosquare.Labs.EmbedIO.Tests { using NUnit.Framework; using System; @@ -124,7 +126,7 @@ public async Task GetEtag() public void GetInitialPartial() { const int maxLength = 100; - var request = (HttpWebRequest)WebRequest.Create(WebServerUrl + "/" + TestHelper.BigDataFile); + var request = (HttpWebRequest)WebRequest.Create(WebServerUrl + TestHelper.BigDataFile); request.AddRange(0, maxLength - 1); using (var response = (HttpWebResponse)request.GetResponse()) @@ -150,7 +152,7 @@ public void GetMiddlePartial() { const int offset = 50; const int maxLength = 100; - var request = (HttpWebRequest)WebRequest.Create(WebServerUrl + "/" + TestHelper.BigDataFile); + var request = (HttpWebRequest)WebRequest.Create(WebServerUrl + TestHelper.BigDataFile); request.AddRange(offset, maxLength + offset - 1); using (var response = (HttpWebResponse)request.GetResponse()) @@ -176,7 +178,7 @@ public void GetLastPart() { const int startByteIndex = 100; const int byteLength = 100; - var request = (HttpWebRequest)WebRequest.Create(WebServerUrl + "/" + TestHelper.BigDataFile); + var request = (HttpWebRequest)WebRequest.Create(WebServerUrl + TestHelper.BigDataFile); request.AddRange(startByteIndex, startByteIndex + byteLength - 1); using (var response = (HttpWebResponse)request.GetResponse()) @@ -198,10 +200,10 @@ public void GetLastPart() } [Test] - public void GetEntireFileWithChunks() + public void GetEntireFileWithChunksUsingRange() { var originalSet = TestHelper.GetBigData(); - var requestHead = (HttpWebRequest)WebRequest.Create(WebServerUrl + "/" + TestHelper.BigDataFile); + var requestHead = (HttpWebRequest)WebRequest.Create(WebServerUrl + TestHelper.BigDataFile); requestHead.Method = "HEAD"; var remoteSize = ((HttpWebResponse)requestHead.GetResponse()).ContentLength; @@ -212,7 +214,7 @@ public void GetEntireFileWithChunks() for (var i = 0; i < remoteSize / chunkSize + 1; i++) { - var request = (HttpWebRequest)WebRequest.Create(WebServerUrl + "/" + TestHelper.BigDataFile); + var request = (HttpWebRequest)WebRequest.Create(WebServerUrl + TestHelper.BigDataFile); var top = (i + 1) * chunkSize; request.AddRange(i * chunkSize, (top > remoteSize ? remoteSize : top) - 1); @@ -234,17 +236,31 @@ public void GetEntireFileWithChunks() Assert.AreEqual(originalSet, buffer); } +#if CHUNKED + [Test] + public async Task GetEntireFileWithChunksUsingChunkedEncoding() + { + using (var client = new HttpClient()) + { + client.DefaultRequestHeaders.TransferEncoding.Add(new TransferCodingHeaderValue("chunked")); + var data = await client.GetByteArrayAsync(WebServerUrl + TestHelper.SmallDataFile); + + Assert.AreEqual(TestHelper.GetSmallData(), data, "Same content data file"); + } + } +#endif + [Test] public async Task GetInvalidChunk() { var originalSet = TestHelper.GetBigData(); - var requestHead = (HttpWebRequest)WebRequest.Create(WebServerUrl + "/" + TestHelper.BigDataFile); + var requestHead = (HttpWebRequest)WebRequest.Create(WebServerUrl + TestHelper.BigDataFile); requestHead.Method = "HEAD"; var remoteSize = ((HttpWebResponse)await requestHead.GetResponseAsync()).ContentLength; Assert.AreEqual(remoteSize, originalSet.Length); - var request = (HttpWebRequest)WebRequest.Create(WebServerUrl + "/" + TestHelper.BigDataFile); + var request = (HttpWebRequest)WebRequest.Create(WebServerUrl + TestHelper.BigDataFile); request.AddRange(0, remoteSize + 10); try @@ -271,7 +287,7 @@ public async Task GetInvalidChunk() [Test] public async Task GetNotPartial() { - var request = (HttpWebRequest)WebRequest.Create(WebServerUrl + "/" + TestHelper.BigDataFile); + var request = (HttpWebRequest)WebRequest.Create(WebServerUrl + TestHelper.BigDataFile); using (var response = (HttpWebResponse)await request.GetResponseAsync()) { diff --git a/test/Unosquare.Labs.EmbedIO.Tests/project.json b/test/Unosquare.Labs.EmbedIO.Tests/project.json index 5f35aa946..f5d2145ac 100644 --- a/test/Unosquare.Labs.EmbedIO.Tests/project.json +++ b/test/Unosquare.Labs.EmbedIO.Tests/project.json @@ -6,7 +6,7 @@ }, "dependencies": { "dotnet-test-nunit": "3.4.0-beta-3", - "NUnit": "3.6.0", + "NUnit": "3.6.1", "Unosquare.Labs.EmbedIO": { "target": "project" } }, @@ -17,7 +17,7 @@ "imports": "dnxcore50", "dependencies": { "Microsoft.NETCore.App": "1.1.0", - "System.Net.Http": "4.3.0" + "System.Net.Http": "4.3.1" } }, "net452": {