From f84b7fda77951e39fa57804559f16150d3db6ea5 Mon Sep 17 00:00:00 2001 From: esskar Date: Fri, 3 Oct 2014 08:23:46 +0200 Subject: [PATCH 01/26] fix demo: call Get from DerivedController when surfing to /Derived --- uhttpsharp-demo/Controllers/DemoController.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/uhttpsharp-demo/Controllers/DemoController.cs b/uhttpsharp-demo/Controllers/DemoController.cs index f9a667e..d61aaa4 100644 --- a/uhttpsharp-demo/Controllers/DemoController.cs +++ b/uhttpsharp-demo/Controllers/DemoController.cs @@ -54,9 +54,9 @@ public Task Post([FromPost("a")] MyRequest request, [FromHe } [Indexer] - public async Task Get(IHttpContext context, int id) + public Task Get(IHttpContext context, int id) { - return new MyController(id); + return Task.FromResult(new MyController(id)); } } public class MyRequest : IValidate @@ -75,7 +75,7 @@ class BaseController : IController [HttpMethod(HttpMethods.Get)] public Task Get() { - return Response.Render(HttpResponseCode.Ok, new {Hello="Base!", Kaki = Enumerable.Range(0, 10000)}); + return Response.Render(HttpResponseCode.Ok, new { Hello = "Base!", Kaki = Enumerable.Range(0, 10000) }); } [HttpMethod(HttpMethods.Post)] @@ -89,14 +89,16 @@ public virtual IPipeline Pipeline get { return new EmptyPipeline(); } } - public IController Derived { + public IController Derived + { get { return new DerivedController(); } } } class DerivedController : BaseController { - protected new Task Get() + [HttpMethod(HttpMethods.Get)] + public new Task Get() { return Response.Render(HttpResponseCode.Ok, new { Hello = "Derived!" }); } From eca934d1a7825ce862883875e2c4755b275e0e1b Mon Sep 17 00:00:00 2001 From: esskar Date: Fri, 3 Oct 2014 08:38:53 +0200 Subject: [PATCH 02/26] allow specifing a equality comparer for comparing route names in ControllerHandler --- uhttpsharp/Handlers/ControllerHandler.cs | 64 ++++++++++++++++-------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/uhttpsharp/Handlers/ControllerHandler.cs b/uhttpsharp/Handlers/ControllerHandler.cs index 3576233..c9a07c9 100644 --- a/uhttpsharp/Handlers/ControllerHandler.cs +++ b/uhttpsharp/Handlers/ControllerHandler.cs @@ -59,26 +59,33 @@ sealed class ControllerRoute { private readonly Type _controllerType; private readonly string _propertyName; - public ControllerRoute(Type controllerType, string propertyName) + private readonly IEqualityComparer _propertyNameComparer; + + public ControllerRoute(Type controllerType, string propertyName, IEqualityComparer propertyNameComparer) { _controllerType = controllerType; _propertyName = propertyName; + _propertyNameComparer = propertyNameComparer; } private bool Equals(ControllerRoute other) { - return _controllerType == other._controllerType && string.Equals(_propertyName, other._propertyName); + return other != null + && _controllerType == other._controllerType + && _propertyNameComparer.Equals(_propertyName, other._propertyName); } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - return obj is ControllerRoute && Equals((ControllerRoute)obj); + + return Equals(obj as ControllerRoute); } public override int GetHashCode() { unchecked { - return ((_controllerType != null ? _controllerType.GetHashCode() : 0)*397) ^ (_propertyName != null ? _propertyName.GetHashCode() : 0); + return ((_controllerType != null ? _controllerType.GetHashCode() : 0) * 397) ^ + (_propertyName != null ? _propertyNameComparer.GetHashCode(_propertyName) : 0); } } } @@ -98,12 +105,26 @@ public override int GetHashCode() private readonly IController _controller; private readonly IModelBinder _modelBinder; private readonly IView _view; + private readonly IEqualityComparer _propertyNameComparer; public ControllerHandler(IController controller, IModelBinder modelBinder, IView view) + : this(controller, modelBinder, view, StringComparer.CurrentCulture) { } + + public ControllerHandler(IController controller, IModelBinder modelBinder, IView view, IEqualityComparer propertyNameComparer) { + if (controller == null) + throw new ArgumentNullException("controller"); + if (modelBinder == null) + throw new ArgumentNullException("modelBinder"); + if (view == null) + throw new ArgumentNullException("view"); + if (propertyNameComparer == null) + throw new ArgumentNullException("propertyNameComparer"); + _controller = controller; _modelBinder = modelBinder; _view = view; + _propertyNameComparer = propertyNameComparer; } protected virtual IModelBinder ModelBinder { @@ -112,10 +133,13 @@ protected virtual IModelBinder ModelBinder private static Func GenerateRouteFunction(MethodInfo getter) { + if (getter.DeclaringType == null) + throw new ArgumentException("Cannot generate route function for static method."); + var instance = Expression.Parameter(typeof(IController), "instance"); - return Expression.Lambda>(Expression.Call(Expression.Convert(instance,getter.DeclaringType),getter),instance).Compile(); + return Expression.Lambda>(Expression.Call(Expression.Convert(instance, getter.DeclaringType), getter), instance).Compile(); } - private static void LoadRoutes(Type controllerType) + private static void LoadRoutes(Type controllerType, IEqualityComparer propertyNameComparer) { if (!LoadedControllerRoutes.Contains(controllerType)) { @@ -123,9 +147,9 @@ private static void LoadRoutes(Type controllerType) { if (!LoadedControllerRoutes.Contains(controllerType)) { - foreach (var prop in controllerType.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p=>p.PropertyType == typeof(IController))) + foreach (var prop in controllerType.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.PropertyType == typeof(IController))) { - Routes.Add(new ControllerRoute(controllerType, prop.Name), + Routes.Add(new ControllerRoute(controllerType, prop.Name, propertyNameComparer), GenerateRouteFunction(prop.GetMethod)); } // Indexers @@ -145,14 +169,14 @@ public async Task Handle(IHttpContext context, Func next) { // I/O Bound? var controller = await GetController(context.Request.RequestParameters, context).ConfigureAwait(false); - + if (controller == null) { await next().ConfigureAwait(false); return; } - var response = await controller.Pipeline.Go(()=>CallMethod(context,controller), context).ConfigureAwait(false); + var response = await controller.Pipeline.Go(() => CallMethod(context, controller), context).ConfigureAwait(false); context.Response = await response.Respond(context, _view).ConfigureAwait(false); @@ -164,9 +188,9 @@ private async Task GetController(IEnumerable requestParamet { var controllerType = current.GetType(); - LoadRoutes(controllerType); + LoadRoutes(controllerType, _propertyNameComparer); - var route = new ControllerRoute(controllerType, parameter); + var route = new ControllerRoute(controllerType, parameter, _propertyNameComparer); Func routeFunction; if (Routes.TryGetValue(route, out routeFunction)) @@ -176,10 +200,10 @@ private async Task GetController(IEnumerable requestParamet } // Try find indexer. - Func> indexerFunction; + Func> indexerFunction; if (IndexerRoutes.TryGetValue(controllerType, out indexerFunction)) { - current = await indexerFunction(context,current, parameter).ConfigureAwait(false); + current = await indexerFunction(context, current, parameter).ConfigureAwait(false); continue; } @@ -195,7 +219,7 @@ private Task CallMethod(IHttpContext context, IController c ControllerFunction controllerFunction; if (!ControllerFunctions.TryGetValue(controllerMethod, out controllerFunction)) - { + { lock (SyncRoot) { if (!ControllerFunctions.TryGetValue(controllerMethod, out controllerFunction)) @@ -216,12 +240,12 @@ private ControllerFunction CreateControllerFunction(ControllerMethod controllerM var controllerArgument = Expression.Parameter(typeof(object), "controller"); var errorContainerVariable = Expression.Variable(typeof(IErrorContainer)); - + var foundMethod = (from method in controllerMethod.ControllerType.GetMethods(BindingFlags.Instance | BindingFlags.Public) - let attribute = method.GetCustomAttribute() - where attribute != null && attribute.HttpMethod == controllerMethod.Method - select method).FirstOrDefault(); + let attribute = method.GetCustomAttribute() + where attribute != null && attribute.HttpMethod == controllerMethod.Method + select method).FirstOrDefault(); if (foundMethod == null) { @@ -291,7 +315,7 @@ private ControllerFunction CreateControllerFunction(ControllerMethod controllerM private Task MethodNotFoundControllerFunction(IHttpContext context, IModelBinder binder, object controller) { // TODO : MethodNotFound. - return Task.FromResult(new RenderResponse(HttpResponseCode.MethodNotAllowed, new { Message = "Not Allowed"})); + return Task.FromResult(new RenderResponse(HttpResponseCode.MethodNotAllowed, new { Message = "Not Allowed" })); } } From 6f895cfe91f74a035a7250c4dc2ecc8b7bd8ac13 Mon Sep 17 00:00:00 2001 From: esskar Date: Fri, 3 Oct 2014 08:39:55 +0200 Subject: [PATCH 03/26] change demo to compare route name case-insensitive --- uhttpsharp-demo/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uhttpsharp-demo/Program.cs b/uhttpsharp-demo/Program.cs index b155899..177737e 100644 --- a/uhttpsharp-demo/Program.cs +++ b/uhttpsharp-demo/Program.cs @@ -49,7 +49,7 @@ private static void Main() //httpServer.Use(new SessionHandler(() => DateTime.Now)); httpServer.Use(new ExceptionHandler()); httpServer.Use(new CompressionHandler(DeflateCompressor.Default, GZipCompressor.Default)); - httpServer.Use(new ControllerHandler(new BaseController(), new JsonModelBinder(), new JsonView())); + httpServer.Use(new ControllerHandler(new BaseController(), new JsonModelBinder(), new JsonView(), StringComparer.OrdinalIgnoreCase)); httpServer.Use(new HttpRouter().With(string.Empty, new IndexHandler()) .With("about", new AboutHandler()) .With("Assets", new AboutHandler()) From 4b0fb119e261e2fc315380aee7a31fb68b946dae Mon Sep 17 00:00:00 2001 From: Shani Elharrar Date: Wed, 4 Feb 2015 09:35:29 +0200 Subject: [PATCH 04/26] Fixed a bug when IHttpResponse used to write to the Writer.BaseStream Flushing the writer before calling response.WriteBody --- uhttpsharp.dll.nuspec | 2 +- uhttpsharp/HttpClient.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/uhttpsharp.dll.nuspec b/uhttpsharp.dll.nuspec index cdce868..0344bc8 100644 --- a/uhttpsharp.dll.nuspec +++ b/uhttpsharp.dll.nuspec @@ -2,7 +2,7 @@ uHttpSharp - 0.1.6.11 + 0.1.6.12 uHttpSharp Shani Elharrar, Joe White, Hüseyin Uslu Shani Elharrar, Joe White, Hüseyin Uslu diff --git a/uhttpsharp/HttpClient.cs b/uhttpsharp/HttpClient.cs index 19b46b5..5872984 100644 --- a/uhttpsharp/HttpClient.cs +++ b/uhttpsharp/HttpClient.cs @@ -137,6 +137,7 @@ await writer.WriteAsync(context.Cookies.ToCookieData()) // Empty Line await writer.WriteLineAsync().ConfigureAwait(false); + writer.Flush(); // Body await response.WriteBody(writer).ConfigureAwait(false); From a1e5218690ccc270e6f7166b8ab340ab94fa86a7 Mon Sep 17 00:00:00 2001 From: Shani Elharrar Date: Sun, 15 Mar 2015 14:01:31 +0200 Subject: [PATCH 05/26] Using IStreamReader with internal implementation. --- uhttpsharp.dll.nuspec | 2 +- uhttpsharp/Headers/HttpHeaders.cs | 13 +- uhttpsharp/HttpClient.cs | 12 +- uhttpsharp/LimitedStream.cs | 98 +++++++++++++- .../RequestProviders/HttpRequestProvider.cs | 19 ++- ...pRequestProviderMethodOverrideDecorator.cs | 3 +- .../RequestProviders/IHttpRequestProvider.cs | 3 +- uhttpsharp/RequestProviders/IStreamReader.cs | 122 ++++++++++++++++++ uhttpsharp/uhttpsharp.csproj | 1 + 9 files changed, 250 insertions(+), 23 deletions(-) create mode 100644 uhttpsharp/RequestProviders/IStreamReader.cs diff --git a/uhttpsharp.dll.nuspec b/uhttpsharp.dll.nuspec index 0344bc8..518626f 100644 --- a/uhttpsharp.dll.nuspec +++ b/uhttpsharp.dll.nuspec @@ -2,7 +2,7 @@ uHttpSharp - 0.1.6.12 + 0.1.6.13 uHttpSharp Shani Elharrar, Joe White, Hüseyin Uslu Shani Elharrar, Joe White, Hüseyin Uslu diff --git a/uhttpsharp/Headers/HttpHeaders.cs b/uhttpsharp/Headers/HttpHeaders.cs index 50be7a6..66d708d 100644 --- a/uhttpsharp/Headers/HttpHeaders.cs +++ b/uhttpsharp/Headers/HttpHeaders.cs @@ -6,6 +6,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using log4net; +using uhttpsharp.RequestProviders; namespace uhttpsharp.Headers { @@ -43,15 +45,10 @@ public IHttpHeaders Parsed internal class HttpPost : IHttpPost { - public static async Task Create(StreamReader reader, int postContentLength) + public static async Task Create(IStreamReader reader, int postContentLength, ILog logger) { - char[] rawEncoded = new char[postContentLength]; - - int readBytes = await reader.ReadAsync(rawEncoded, 0, rawEncoded.Length).ConfigureAwait(false); - - byte[] raw = Encoding.UTF8.GetBytes(rawEncoded, 0, readBytes); - - return new HttpPost(raw, readBytes); + byte[] raw = await reader.ReadBytes(postContentLength).ConfigureAwait(false); + return new HttpPost(raw, postContentLength); } private readonly int _readBytes; diff --git a/uhttpsharp/HttpClient.cs b/uhttpsharp/HttpClient.cs index 5872984..8366f00 100644 --- a/uhttpsharp/HttpClient.cs +++ b/uhttpsharp/HttpClient.cs @@ -23,6 +23,8 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Net.Sockets; using System.Threading.Tasks; using uhttpsharp.Clients; using uhttpsharp.Headers; @@ -51,7 +53,7 @@ public HttpClientHandler(IClient client, Func requestHandler _requestHandler = requestHandler; _requestProvider = requestProvider; - _stream = new BufferedStream(_client.Stream, 8192); + _stream = new BufferedStream(_client.Stream, 8096); Logger.InfoFormat("Got Client {0}", _remoteEndPoint); @@ -67,10 +69,9 @@ private async void Process() while (_client.Connected) { // TODO : Configuration. - var limitedStream = new NotFlushingStream(new LimitedStream(_stream, readLimit: 1024*1024, writeLimit: 1024*1024)); - var streamReader = new StreamReader(limitedStream); - - var request = await _requestProvider.Provide(streamReader).ConfigureAwait(false); + var limitedStream = new NotFlushingStream(new LimitedStream(_stream)); + + var request = await _requestProvider.Provide(new MyStreamReader(limitedStream)).ConfigureAwait(false); if (request != null) { @@ -80,6 +81,7 @@ private async void Process() Logger.InfoFormat("{1} : Got request {0}", request.Uri, _client.RemoteEndPoint); + await _requestHandler(context).ConfigureAwait(false); if (context.Response != null) diff --git a/uhttpsharp/LimitedStream.cs b/uhttpsharp/LimitedStream.cs index e4c5969..ef8328b 100644 --- a/uhttpsharp/LimitedStream.cs +++ b/uhttpsharp/LimitedStream.cs @@ -1,7 +1,103 @@ -using System.IO; +using System; +using System.IO; +using System.Text; namespace uhttpsharp { + class LoggingStream : Stream + { + private readonly Stream _child; + + private readonly string _tempFileName = Path.GetTempFileName(); + public LoggingStream(Stream child) + { + _child = child; + + Console.WriteLine("Logging to " + _tempFileName); + } + + public override void Flush() + { + _child.Flush(); + } + + public override long Seek(long offset, SeekOrigin origin) + { + return _child.Seek(offset, origin); + } + public override void SetLength(long value) + { + _child.SetLength(value); + } + public override int Read(byte[] buffer, int offset, int count) + { + var retVal = _child.Read(buffer, offset, count); + + using (var stream = File.Open(_tempFileName, FileMode.Append)) + { + stream.Seek(0, SeekOrigin.End); + stream.Write(buffer, offset, retVal); + } + + return retVal; + } + + public override int ReadByte() + { + var retVal = _child.ReadByte(); + + using (var stream = File.Open(_tempFileName, FileMode.Append)) + { + stream.Seek(0, SeekOrigin.End); + stream.WriteByte((byte)retVal); + } + + return retVal; + } + public override void Write(byte[] buffer, int offset, int count) + { + _child.Write(buffer, offset, count); + + } + public override void WriteByte(byte value) + { + _child.WriteByte(value); + + } + public override bool CanRead + { + get { return _child.CanRead; } + } + public override bool CanSeek + { + get { return _child.CanSeek; } + } + + public override bool CanWrite + { + get { return _child.CanWrite; } + } + public override long Length + { + get { return _child.Length; } + } + public override long Position + { + get { return _child.Position; } + set { _child.Position = value; } + } + public override int ReadTimeout + { + get { return _child.ReadTimeout; } + set { _child.ReadTimeout = value; } + } + public override int WriteTimeout + { + get { return _child.WriteTimeout; } + set { _child.WriteTimeout = value; } + } + } + class LimitedStream : Stream { private const string _exceptionMessageFormat = "The Stream has exceeded the {0} limit specified."; diff --git a/uhttpsharp/RequestProviders/HttpRequestProvider.cs b/uhttpsharp/RequestProviders/HttpRequestProvider.cs index 9589bda..8edb5df 100644 --- a/uhttpsharp/RequestProviders/HttpRequestProvider.cs +++ b/uhttpsharp/RequestProviders/HttpRequestProvider.cs @@ -2,7 +2,10 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net.Sockets; +using System.Text; using System.Threading.Tasks; +using log4net; using uhttpsharp.Headers; namespace uhttpsharp.RequestProviders @@ -11,10 +14,13 @@ public class HttpRequestProvider : IHttpRequestProvider { private static readonly char[] Separators = { '/' }; - public async Task Provide(StreamReader streamReader) + private static readonly ILog Logger = LogManager.GetLogger(typeof(HttpRequestProvider)); + + + public async Task Provide(IStreamReader reader) { // parse the http request - var request = await streamReader.ReadLineAsync().ConfigureAwait(false); + var request = await reader.ReadLine().ConfigureAwait(false); if (request == null) return null; @@ -46,7 +52,7 @@ public async Task Provide(StreamReader streamReader) // get the headers string line; - while (!string.IsNullOrEmpty((line = await streamReader.ReadLineAsync().ConfigureAwait(false)))) + while (!string.IsNullOrEmpty((line = await reader.ReadLine().ConfigureAwait(false)))) { string currentLine = line; @@ -55,7 +61,7 @@ public async Task Provide(StreamReader streamReader) } IHttpHeaders headers = new HttpHeaders(headersRaw.ToDictionary(k => k.Key, k => k.Value, StringComparer.InvariantCultureIgnoreCase)); - IHttpPost post = await GetPostData(streamReader, headers).ConfigureAwait(false); + IHttpPost post = await GetPostData(reader, headers).ConfigureAwait(false); string verb; if (!headers.TryGetByName("_method", out verb)) @@ -66,6 +72,7 @@ public async Task Provide(StreamReader streamReader) return new HttpRequest(headers, httpMethod, httpProtocol, uri, uri.OriginalString.Split(Separators, StringSplitOptions.RemoveEmptyEntries), queryString, post); } + private static IHttpHeaders GetQueryStringData(ref string url) { var queryStringIndex = url.IndexOf('?'); @@ -82,13 +89,13 @@ private static IHttpHeaders GetQueryStringData(ref string url) return queryString; } - private static async Task GetPostData(StreamReader streamReader, IHttpHeaders headers) + private static async Task GetPostData(IStreamReader streamReader, IHttpHeaders headers) { int postContentLength; IHttpPost post; if (headers.TryGetByName("content-length", out postContentLength) && postContentLength > 0) { - post = await HttpPost.Create(streamReader, postContentLength).ConfigureAwait(false); + post = await HttpPost.Create(streamReader, postContentLength, Logger).ConfigureAwait(false); } else { diff --git a/uhttpsharp/RequestProviders/HttpRequestProviderMethodOverrideDecorator.cs b/uhttpsharp/RequestProviders/HttpRequestProviderMethodOverrideDecorator.cs index 5f12a0a..b2b6ecd 100644 --- a/uhttpsharp/RequestProviders/HttpRequestProviderMethodOverrideDecorator.cs +++ b/uhttpsharp/RequestProviders/HttpRequestProviderMethodOverrideDecorator.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Net.Sockets; using System.Threading.Tasks; namespace uhttpsharp.RequestProviders @@ -12,7 +13,7 @@ public HttpRequestProviderMethodOverrideDecorator(IHttpRequestProvider child) _child = child; } - public async Task Provide(StreamReader streamReader) + public async Task Provide(IStreamReader streamReader) { var childValue = await _child.Provide(streamReader).ConfigureAwait(false); diff --git a/uhttpsharp/RequestProviders/IHttpRequestProvider.cs b/uhttpsharp/RequestProviders/IHttpRequestProvider.cs index 5171594..763dc0d 100644 --- a/uhttpsharp/RequestProviders/IHttpRequestProvider.cs +++ b/uhttpsharp/RequestProviders/IHttpRequestProvider.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Net.Sockets; using System.Threading.Tasks; namespace uhttpsharp.RequestProviders @@ -11,7 +12,7 @@ public interface IHttpRequestProvider /// /// /// - Task Provide(StreamReader streamReader); + Task Provide(IStreamReader streamReader); } } \ No newline at end of file diff --git a/uhttpsharp/RequestProviders/IStreamReader.cs b/uhttpsharp/RequestProviders/IStreamReader.cs new file mode 100644 index 0000000..f83abca --- /dev/null +++ b/uhttpsharp/RequestProviders/IStreamReader.cs @@ -0,0 +1,122 @@ +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; + +namespace uhttpsharp.RequestProviders +{ + public interface IStreamReader + { + + Task ReadLine(); + + Task ReadBytes(int count); + + + } + class StreamReaderAdapter : IStreamReader + { + private readonly StreamReader _reader; + public StreamReaderAdapter(StreamReader reader) + { + _reader = reader; + } + + public async Task ReadLine() + { + return await _reader.ReadLineAsync().ConfigureAwait(false); + } + public async Task ReadBytes(int count) + { + var tempBuffer = new char[count]; + + await _reader.ReadBlockAsync(tempBuffer, 0, count).ConfigureAwait(false); + + var retVal = new byte[count]; + + for (int i = 0; i < tempBuffer.Length; i++) + { + retVal[i] = (byte)tempBuffer[i]; + } + + return retVal; + } + } + + class MyStreamReader : IStreamReader + { + private const int BufferSize = 8096 / 4; + private readonly Stream _underlyingStream; + + private readonly byte[] _middleBuffer = new byte[BufferSize]; + private int _index; + private int _count; + + public MyStreamReader(Stream underlyingStream) + { + _underlyingStream = underlyingStream; + } + + private async Task ReadBuffer() + { + do + { + _count = await _underlyingStream.ReadAsync(_middleBuffer, 0, BufferSize).ConfigureAwait(false); + } + while (_count == 0); + + _index = 0; + } + + public async Task ReadLine() + { + var builder = new StringBuilder(64); + + if (_index == _count) + { + await ReadBuffer().ConfigureAwait(false); + } + var readByte = _middleBuffer[_index++]; + + while (readByte != '\n' && (builder.Length == 0 || builder[builder.Length - 1] != '\r')) + { + builder.Append((char)readByte); + + if (_index == _count) + { + await ReadBuffer().ConfigureAwait(false); + } + readByte = _middleBuffer[_index++]; + } + + //Debug.WriteLine("Readline : " + sw.ElapsedMilliseconds); + + return builder.ToString(0, builder.Length - 1); + } + + public async Task ReadBytes(int count) + { + var buffer = new byte[count]; + int currentByte = 0; + + // Empty the buffer + int bytesToRead = Math.Min(_count - _index, count) + _index; + for (int i = _index; i < bytesToRead; i++) + { + buffer[currentByte++] = _middleBuffer[i]; + } + + _index = _count; + + // Read from stream + while (currentByte < count) + { + currentByte += await _underlyingStream.ReadAsync(buffer, currentByte, count - currentByte).ConfigureAwait(false); + } + + //Debug.WriteLine("ReadBytes(" + count + ") : " + sw.ElapsedMilliseconds); + + return buffer; + } + } +} \ No newline at end of file diff --git a/uhttpsharp/uhttpsharp.csproj b/uhttpsharp/uhttpsharp.csproj index 404dd0d..4cf5d80 100644 --- a/uhttpsharp/uhttpsharp.csproj +++ b/uhttpsharp/uhttpsharp.csproj @@ -112,6 +112,7 @@ + From 3bce97511ce7b16ce2bb3b5c7c3558fa4fabb244 Mon Sep 17 00:00:00 2001 From: Shani Elharrar Date: Sun, 15 Mar 2015 16:33:18 +0200 Subject: [PATCH 06/26] Fixed a 100% cpu bug when readtimeout was -1 --- uhttpsharp.dll.nuspec | 2 +- uhttpsharp.sln.DotSettings.user | 57 ++++++++++++++++++++++++++ uhttpsharp/Clients/TcpClientAdapter.cs | 7 +++- 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 uhttpsharp.sln.DotSettings.user diff --git a/uhttpsharp.dll.nuspec b/uhttpsharp.dll.nuspec index 518626f..e77dff1 100644 --- a/uhttpsharp.dll.nuspec +++ b/uhttpsharp.dll.nuspec @@ -2,7 +2,7 @@ uHttpSharp - 0.1.6.13 + 0.1.6.14 uHttpSharp Shani Elharrar, Joe White, Hüseyin Uslu Shani Elharrar, Joe White, Hüseyin Uslu diff --git a/uhttpsharp.sln.DotSettings.user b/uhttpsharp.sln.DotSettings.user new file mode 100644 index 0000000..7cd8d6c --- /dev/null +++ b/uhttpsharp.sln.DotSettings.user @@ -0,0 +1,57 @@ + + 0 + 0 + False + False + 1 + 1 + 0 + 0 + 0 + 128 + + $object$_On$event$ + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> + <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + + $object$_On$event$ + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> + <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + True + True + True \ No newline at end of file diff --git a/uhttpsharp/Clients/TcpClientAdapter.cs b/uhttpsharp/Clients/TcpClientAdapter.cs index 9661caa..994717f 100644 --- a/uhttpsharp/Clients/TcpClientAdapter.cs +++ b/uhttpsharp/Clients/TcpClientAdapter.cs @@ -7,15 +7,20 @@ namespace uhttpsharp.Clients public class TcpClientAdapter : IClient { private readonly TcpClient _client; + private readonly NetworkStream _stream; public TcpClientAdapter(TcpClient client) { _client = client; + _stream = _client.GetStream(); + + // Read Timeout of one second. + _stream.ReadTimeout = 1000; } public Stream Stream { - get { return _client.GetStream(); } + get { return _stream; } } public bool Connected From 6b4ba396e14a9e4c5d0a92e69831155ddc525ee8 Mon Sep 17 00:00:00 2001 From: Shani Elharrar Date: Thu, 19 Mar 2015 15:32:56 +0200 Subject: [PATCH 07/26] BugFix : ClassRouter - String indexer functions --- uhttpsharp.dll.nuspec | 2 +- uhttpsharp/Handlers/ClassRouter.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/uhttpsharp.dll.nuspec b/uhttpsharp.dll.nuspec index e77dff1..7e13a9d 100644 --- a/uhttpsharp.dll.nuspec +++ b/uhttpsharp.dll.nuspec @@ -2,7 +2,7 @@ uHttpSharp - 0.1.6.14 + 0.1.6.15 uHttpSharp Shani Elharrar, Joe White, Hüseyin Uslu Shani Elharrar, Joe White, Hüseyin Uslu diff --git a/uhttpsharp/Handlers/ClassRouter.cs b/uhttpsharp/Handlers/ClassRouter.cs index d4dc850..145d6bd 100644 --- a/uhttpsharp/Handlers/ClassRouter.cs +++ b/uhttpsharp/Handlers/ClassRouter.cs @@ -136,7 +136,7 @@ internal static Func> CreateIndexerFunction( Expression.Constant(parameterType)), parameterType); var indexerExpression = Expression.Call (handlerConverted, indexer, httpContext, objectConverted); - var returnValue = Expression.Convert (indexerExpression, typeof(T)); + var returnValue = Expression.Convert (indexerExpression, typeof(Task)); body = returnValue; } From a074a31aedd6319165026ffd742a6d49e3c82bce Mon Sep 17 00:00:00 2001 From: Shani Elharrar Date: Thu, 19 Mar 2015 16:01:29 +0200 Subject: [PATCH 08/26] ControllerHandler : Allow Multiple HttpMethod Attributes --- uhttpsharp.dll.nuspec | 2 +- uhttpsharp/Handlers/ControllerHandler.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/uhttpsharp.dll.nuspec b/uhttpsharp.dll.nuspec index 7e13a9d..df95c7c 100644 --- a/uhttpsharp.dll.nuspec +++ b/uhttpsharp.dll.nuspec @@ -2,7 +2,7 @@ uHttpSharp - 0.1.6.15 + 0.1.6.16 uHttpSharp Shani Elharrar, Joe White, Hüseyin Uslu Shani Elharrar, Joe White, Hüseyin Uslu diff --git a/uhttpsharp/Handlers/ControllerHandler.cs b/uhttpsharp/Handlers/ControllerHandler.cs index c9a07c9..411d5ad 100644 --- a/uhttpsharp/Handlers/ControllerHandler.cs +++ b/uhttpsharp/Handlers/ControllerHandler.cs @@ -243,8 +243,8 @@ private ControllerFunction CreateControllerFunction(ControllerMethod controllerM var foundMethod = (from method in controllerMethod.ControllerType.GetMethods(BindingFlags.Instance | BindingFlags.Public) - let attribute = method.GetCustomAttribute() - where attribute != null && attribute.HttpMethod == controllerMethod.Method + let attributes = method.GetCustomAttributes() + where attributes.Any(a => a.HttpMethod == controllerMethod.Method) select method).FirstOrDefault(); if (foundMethod == null) From 80b1fb79950f459ab4b8557cdd5f4ba53ea7cd44 Mon Sep 17 00:00:00 2001 From: Jonathon Douglas Date: Thu, 19 Mar 2015 16:57:18 +0000 Subject: [PATCH 09/26] Changed MainProject Logging from log4net to LibLog and Updated Newtonsoft.Json Changed Tests to use XUnit, Shoudly and NSubstitute --- .gitignore | 232 +- uhttpsharp-demo/Handlers/TimingHandler.cs | 4 +- uhttpsharp-demo/Program.cs | 2 - uhttpsharp-demo/packages.config | 3 +- uhttpsharp-demo/uhttpsharp.Demo.csproj | 5 +- .../HttpMethodProviderCacheTests.cs | 32 +- uhttpsharp.Tests/HttpMethodProviderTests.cs | 24 +- uhttpsharp.Tests/packages.config | 11 +- uhttpsharp.Tests/uhttpsharp.Tests.csproj | 31 +- uhttpsharp.dll.nuspec | 3 +- uhttpsharp/App_Packages/LibLog.3.1/LibLog.cs | 1941 +++++++++++++++++ uhttpsharp/Headers/HttpHeaders.cs | 2 +- uhttpsharp/HttpClient.cs | 6 +- uhttpsharp/HttpServer.cs | 6 +- .../RequestProviders/HttpRequestProvider.cs | 7 +- uhttpsharp/packages.config | 4 +- uhttpsharp/uhttpsharp.csproj | 9 +- 17 files changed, 2257 insertions(+), 65 deletions(-) create mode 100644 uhttpsharp/App_Packages/LibLog.3.1/LibLog.cs diff --git a/.gitignore b/.gitignore index 5b85ade..9d62ca3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,227 @@ -/_ReSharper.uhttpsharp/ -/*.6.0.ReSharper.user -/*.suo -/packages/* -*/bin/* -*/obj/* +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Visual Studio 2015 cache/options directory +*.vs/ + +# Roslyn cache directories +*.ide/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler *.psess *.vsp -*.nupkg \ No newline at end of file +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +## TODO: Comment the next line if you want to checkin your +## web deploy settings but do note that will include unencrypted +## passwords +*.pubxml +*.publishproj + +# NuGet Packages Directory +packages/* +*.nupkg + +## TODO: If the tool you use requires repositories.config +## uncomment the next line +#!packages/repositories.config + +# Enable "build/" folder in the NuGet Packages folder since +# NuGet packages use it for MSBuild targets. +# This line needs to be after the ignore of the build folder +# (and the packages folder if the line above has been uncommented) +!packages/build/ + +# PVC Build packages (https://github.com/pvcbuild/pvc) +pvc-packages/* + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.[Pp]ublish.xml +*.pfx +*.publishsettings +node_modules/ +bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Paket Package Manager Main exe +.paket/paket.exe + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store diff --git a/uhttpsharp-demo/Handlers/TimingHandler.cs b/uhttpsharp-demo/Handlers/TimingHandler.cs index 91ab79e..f37504e 100644 --- a/uhttpsharp-demo/Handlers/TimingHandler.cs +++ b/uhttpsharp-demo/Handlers/TimingHandler.cs @@ -2,14 +2,14 @@ using System.Diagnostics; using System.Reflection; using System.Threading.Tasks; -using log4net; using uhttpsharp; +using uhttpsharp.Logging; namespace uhttpsharpdemo.Handlers { public class TimingHandler : IHttpRequestHandler { - private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog Logger = LogProvider.GetCurrentClassLogger(); public async Task Handle(IHttpContext context, Func next) { diff --git a/uhttpsharp-demo/Program.cs b/uhttpsharp-demo/Program.cs index 177737e..4d07921 100644 --- a/uhttpsharp-demo/Program.cs +++ b/uhttpsharp-demo/Program.cs @@ -37,8 +37,6 @@ internal static class Program { private static void Main() { - log4net.Config.XmlConfigurator.Configure(); - //var serverCertificate = X509Certificate.CreateFromCertFile(@"TempCert.cer"); using (var httpServer = new HttpServer(new HttpRequestProvider())) diff --git a/uhttpsharp-demo/packages.config b/uhttpsharp-demo/packages.config index a8e7b37..747efc5 100644 --- a/uhttpsharp-demo/packages.config +++ b/uhttpsharp-demo/packages.config @@ -1,5 +1,4 @@  - - + \ No newline at end of file diff --git a/uhttpsharp-demo/uhttpsharp.Demo.csproj b/uhttpsharp-demo/uhttpsharp.Demo.csproj index 7563180..62d1a20 100644 --- a/uhttpsharp-demo/uhttpsharp.Demo.csproj +++ b/uhttpsharp-demo/uhttpsharp.Demo.csproj @@ -39,12 +39,9 @@ false - - ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll - False - ..\packages\Newtonsoft.Json.6.0.3\lib\net45\Newtonsoft.Json.dll + ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll diff --git a/uhttpsharp.Tests/HttpMethodProviderCacheTests.cs b/uhttpsharp.Tests/HttpMethodProviderCacheTests.cs index 85a8f53..9f42c2d 100644 --- a/uhttpsharp.Tests/HttpMethodProviderCacheTests.cs +++ b/uhttpsharp.Tests/HttpMethodProviderCacheTests.cs @@ -1,9 +1,9 @@ -using Moq; -using NUnit.Framework; +using NSubstitute; +using Shouldly; +using Xunit; namespace uhttpsharp.Tests { - [TestFixture] public class HttpMethodProviderCacheTests { private const string MethodName = "Hello World"; @@ -13,44 +13,44 @@ private static IHttpMethodProvider GetTarget(IHttpMethodProvider child) return new HttpMethodProviderCache(child); } - [Test] + [Fact] public void Should_Call_Child_With_Right_Parameters() { // Arrange - var mock = new Mock(); - var target = GetTarget(mock.Object); + var mock = Substitute.For(); + var target = GetTarget(mock); // Act target.Provide(MethodName); // Assert - mock.Verify(m => m.Provide(MethodName), Times.Once); + mock.Received(1).Provide(MethodName); } - [Test] + [Fact] public void Should_Return_Same_Child_Value() { // Arrange const HttpMethods expectedMethod = HttpMethods.Post; - var mock = new Mock(); - var target = GetTarget(mock.Object); + var mock = Substitute.For(); + mock.Provide(MethodName).Returns(expectedMethod); + var target = GetTarget(mock); - mock.Setup(m => m.Provide(MethodName)).Returns(expectedMethod); // Act var actual = target.Provide(MethodName); // Assert - Assert.That(actual, Is.EqualTo(expectedMethod)); + actual.ShouldBe(expectedMethod); } - [Test] + [Fact] public void Should_Cache_The_Value() { // Arrange - var mock = new Mock(); - var target = GetTarget(mock.Object); + var mock = Substitute.For(); + var target = GetTarget(mock); // Act target.Provide(MethodName); @@ -58,7 +58,7 @@ public void Should_Cache_The_Value() target.Provide(MethodName); // Assert - mock.Verify(m => m.Provide(MethodName), Times.Once); + mock.Received(1).Provide(MethodName); } } diff --git a/uhttpsharp.Tests/HttpMethodProviderTests.cs b/uhttpsharp.Tests/HttpMethodProviderTests.cs index 4589c3a..be12a8d 100644 --- a/uhttpsharp.Tests/HttpMethodProviderTests.cs +++ b/uhttpsharp.Tests/HttpMethodProviderTests.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; -using NUnit.Framework; +using Shouldly; +using Xunit; namespace uhttpsharp.Tests { - [TestFixture] public class HttpMethodProviderTests { @@ -14,25 +14,35 @@ private static IHttpMethodProvider GetTarget() } - private IEnumerable Methods + public static IEnumerable Methods { get { return Enum.GetNames(typeof(HttpMethods)); } } - - [TestCaseSource("Methods")] - public void Should_Get_Right_Method(string methodName) + + [Theory] + [InlineData(HttpMethods.Connect)] + [InlineData(HttpMethods.Delete)] + [InlineData(HttpMethods.Get)] + [InlineData(HttpMethods.Head)] + [InlineData(HttpMethods.Options)] + [InlineData(HttpMethods.Patch)] + [InlineData(HttpMethods.Post)] + [InlineData(HttpMethods.Put)] + [InlineData(HttpMethods.Trace)] + public void Should_Get_Right_Method(HttpMethods method) { // Arrange + var methodName = Enum.GetName(typeof(HttpMethods), method); var target = GetTarget(); // Act var actual = target.Provide(methodName); // Assert - Assert.IsTrue(StringComparer.InvariantCultureIgnoreCase.Equals(actual.ToString(), methodName)); + actual.ToString().ShouldBe(methodName); } } diff --git a/uhttpsharp.Tests/packages.config b/uhttpsharp.Tests/packages.config index c90677c..2917e16 100644 --- a/uhttpsharp.Tests/packages.config +++ b/uhttpsharp.Tests/packages.config @@ -1,5 +1,12 @@  - - + + + + + + + + + \ No newline at end of file diff --git a/uhttpsharp.Tests/uhttpsharp.Tests.csproj b/uhttpsharp.Tests/uhttpsharp.Tests.csproj index 331fb8e..e4d8d2a 100644 --- a/uhttpsharp.Tests/uhttpsharp.Tests.csproj +++ b/uhttpsharp.Tests/uhttpsharp.Tests.csproj @@ -1,5 +1,7 @@  + + Debug @@ -13,6 +15,7 @@ 512 ..\ true + 84fe69d3 true @@ -32,11 +35,14 @@ 4 - - ..\packages\Moq.4.2.1312.1622\lib\net40\Moq.dll + + ..\packages\NSubstitute.1.8.1.0\lib\net45\NSubstitute.dll - ..\packages\NUnit.2.6.3\lib\nunit.framework.dll + ..\packages\NUnit.2.6.4\lib\nunit.framework.dll + + + ..\packages\Shouldly.2.4.0\lib\net40\Shouldly.dll @@ -45,6 +51,15 @@ + + ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll + + + ..\packages\xunit.assert.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.assert.dll + + + ..\packages\xunit.extensibility.core.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.dll + @@ -60,8 +75,18 @@ uhttpsharp + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + diff --git a/uhttpsharp-demo/packages.config b/uhttpsharp-demo/packages.config index 747efc5..639150b 100644 --- a/uhttpsharp-demo/packages.config +++ b/uhttpsharp-demo/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/uhttpsharp-demo/uhttpsharp.Demo.csproj b/uhttpsharp-demo/uhttpsharp.Demo.csproj index 62d1a20..fb380e5 100644 --- a/uhttpsharp-demo/uhttpsharp.Demo.csproj +++ b/uhttpsharp-demo/uhttpsharp.Demo.csproj @@ -39,6 +39,10 @@ false + + False + ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll + False ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll From 3cc87eeae643743079f69e2c4a9da424b6632332 Mon Sep 17 00:00:00 2001 From: Shani Elharrar Date: Tue, 24 Mar 2015 16:33:50 +0200 Subject: [PATCH 18/26] Version Bump! :facepunch: --- uhttpsharp.dll.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uhttpsharp.dll.nuspec b/uhttpsharp.dll.nuspec index 7909a20..4cbd5db 100644 --- a/uhttpsharp.dll.nuspec +++ b/uhttpsharp.dll.nuspec @@ -2,7 +2,7 @@ uHttpSharp - 0.1.6.18 + 0.1.6.19 uHttpSharp Shani Elharrar, Joe White, Hüseyin Uslu Shani Elharrar, Joe White, Hüseyin Uslu From e3f6d7f735400d3768f932eca4b9c1609b757d33 Mon Sep 17 00:00:00 2001 From: Shani Elharrar Date: Sat, 13 Jun 2015 18:36:42 +0300 Subject: [PATCH 19/26] Fixed a lot of "Unable to read data from the transport connection" Related #14 --- uhttpsharp.dll.nuspec | 2 +- uhttpsharp/Clients/TcpClientAdapter.cs | 6 +++++- uhttpsharp/HttpClient.cs | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/uhttpsharp.dll.nuspec b/uhttpsharp.dll.nuspec index 4cbd5db..1255250 100644 --- a/uhttpsharp.dll.nuspec +++ b/uhttpsharp.dll.nuspec @@ -2,7 +2,7 @@ uHttpSharp - 0.1.6.19 + 0.1.6.20 uHttpSharp Shani Elharrar, Joe White, Hüseyin Uslu Shani Elharrar, Joe White, Hüseyin Uslu diff --git a/uhttpsharp/Clients/TcpClientAdapter.cs b/uhttpsharp/Clients/TcpClientAdapter.cs index 994717f..302e56c 100644 --- a/uhttpsharp/Clients/TcpClientAdapter.cs +++ b/uhttpsharp/Clients/TcpClientAdapter.cs @@ -14,8 +14,12 @@ public TcpClientAdapter(TcpClient client) _client = client; _stream = _client.GetStream(); + // The next lines are commented out because they caused exceptions, And i'm not sure why it has been added in the first place. + // See https://github.com/Code-Sharp/uHttpSharp/issues/14 + // Read Timeout of one second. - _stream.ReadTimeout = 1000; + // _stream.ReadTimeout = 1000; + } public Stream Stream diff --git a/uhttpsharp/HttpClient.cs b/uhttpsharp/HttpClient.cs index 4749d11..3bbab9b 100644 --- a/uhttpsharp/HttpClient.cs +++ b/uhttpsharp/HttpClient.cs @@ -71,6 +71,8 @@ private async void Process() // TODO : Configuration. var limitedStream = new NotFlushingStream(new LimitedStream(_stream)); + + var request = await _requestProvider.Provide(new MyStreamReader(limitedStream)).ConfigureAwait(false); if (request != null) From 19924067114ffa738c1c58defadb9007619d6f7a Mon Sep 17 00:00:00 2001 From: Shani Elharrar Date: Wed, 17 Jun 2015 15:05:34 +0300 Subject: [PATCH 20/26] HTTP Basic Authentication Support Fixes #15 --- uhttpsharp-demo/Program.cs | 66 +----------- uhttpsharp.dll.nuspec | 2 +- uhttpsharp.sln.DotSettings.user | 1 + .../Handlers/BasicAuthenticationHandler.cs | 100 ++++++++++++++++++ uhttpsharp/Handlers/SessionHandler.cs | 81 ++++++++++++++ uhttpsharp/HttpResponse.cs | 12 ++- uhttpsharp/uhttpsharp.csproj | 2 + 7 files changed, 198 insertions(+), 66 deletions(-) create mode 100644 uhttpsharp/Handlers/BasicAuthenticationHandler.cs create mode 100644 uhttpsharp/Handlers/SessionHandler.cs diff --git a/uhttpsharp-demo/Program.cs b/uhttpsharp-demo/Program.cs index 755ef81..476f14a 100644 --- a/uhttpsharp-demo/Program.cs +++ b/uhttpsharp-demo/Program.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Concurrent; +using System.Dynamic; using System.Globalization; using System.Net; using System.Net.Sockets; @@ -50,6 +51,8 @@ private static void Main() //httpServer.Use(new SessionHandler(() => DateTime.Now)); httpServer.Use(new ExceptionHandler()); + httpServer.Use(new SessionHandler(() => new ExpandoObject(), TimeSpan.FromMinutes(20))); + httpServer.Use(new BasicAuthenticationHandler("Hohoho", "username", "password5")); httpServer.Use(new ControllerHandler(new DerivedController(), new ModelBinder(new ObjectActivator()), new JsonView())); httpServer.Use(new CompressionHandler(DeflateCompressor.Default, GZipCompressor.Default)); @@ -130,66 +133,5 @@ public System.Threading.Tasks.Task Handle(IHttpContext context, Func : IHttpRequestHandler - { - private readonly Func _sessionFactory; - - private static readonly Random RandomGenerator = new Random(); - - private class SessionHolder - { - private readonly TSession _session; - private DateTime _lastAccessTime = DateTime.Now; - - public TSession Session - { - get - { - _lastAccessTime = DateTime.Now; - return _session; - } - } - - public DateTime LastAccessTime - { - get - { - return _lastAccessTime; - } - } - - public SessionHolder(TSession session) - { - _session = session; - } - } - - private readonly ConcurrentDictionary _sessions = new ConcurrentDictionary(); - - public SessionHandler(Func sessionFactory) - { - _sessionFactory = sessionFactory; - } - - public System.Threading.Tasks.Task Handle(IHttpContext context, Func next) - { - - string sessId; - if (!context.Cookies.TryGetByName("SESSID", out sessId)) - { - sessId = RandomGenerator.Next().ToString(CultureInfo.InvariantCulture); - context.Cookies.Upsert("SESSID", sessId); - } - - var session = _sessions.GetOrAdd(sessId, CreateSession); - - context.State.Session = session; - - return next(); - } - private TSession CreateSession(string sessionId) - { - return _sessionFactory(); - } - } + } \ No newline at end of file diff --git a/uhttpsharp.dll.nuspec b/uhttpsharp.dll.nuspec index 1255250..0cb106d 100644 --- a/uhttpsharp.dll.nuspec +++ b/uhttpsharp.dll.nuspec @@ -2,7 +2,7 @@ uHttpSharp - 0.1.6.20 + 0.1.6.21 uHttpSharp Shani Elharrar, Joe White, Hüseyin Uslu Shani Elharrar, Joe White, Hüseyin Uslu diff --git a/uhttpsharp.sln.DotSettings.user b/uhttpsharp.sln.DotSettings.user index 7cd8d6c..3c320f1 100644 --- a/uhttpsharp.sln.DotSettings.user +++ b/uhttpsharp.sln.DotSettings.user @@ -52,6 +52,7 @@ <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + True True True True \ No newline at end of file diff --git a/uhttpsharp/Handlers/BasicAuthenticationHandler.cs b/uhttpsharp/Handlers/BasicAuthenticationHandler.cs new file mode 100644 index 0000000..0b5af83 --- /dev/null +++ b/uhttpsharp/Handlers/BasicAuthenticationHandler.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using uhttpsharp.Headers; + +namespace uhttpsharp.Handlers +{ + + public class BasicAuthenticationHandler : IHttpRequestHandler + { + private static readonly string BasicPrefix = "Basic "; + private static readonly int BasicPrefixLength = BasicPrefix.Length; + + private readonly string _username; + private readonly string _password; + private readonly string _authenticationKey; + private readonly ListHttpHeaders _headers; + + public BasicAuthenticationHandler(string realm, string username, string password) + { + _username = username; + _password = password; + _authenticationKey = "Authenticated." + realm; + _headers = new ListHttpHeaders(new List> + { + new KeyValuePair("WWW-Authenticate", string.Format(@"Basic realm=""{0}""", realm)) + }); + } + + public Task Handle(IHttpContext context, Func next) + { + IDictionary session = context.State.Session; + dynamic ipAddress; + + if (!session.TryGetValue(_authenticationKey, out ipAddress) || ipAddress != context.RemoteEndPoint) + { + if (TryAuthenticate(context, session)) + { + return next(); + } + + context.Response = + StringHttpResponse.Create("Not Authenticated", HttpResponseCode.Unauthorized, + headers: + _headers); + + return Task.Factory.GetCompleted(); + } + + return next(); + } + + private bool TryAuthenticate(IHttpContext context, IDictionary session) + { + string credentials; + if (context.Request.Headers.TryGetByName("Authorization", out credentials)) + { + + if (TryAuthenticate(credentials)) + { + session[_authenticationKey] = context.RemoteEndPoint; + { + + return true; + } + } + } + return false; + } + + + private bool TryAuthenticate(string credentials) + { + if (!credentials.StartsWith(BasicPrefix)) + { + return false; + } + + var basicCredentials = credentials.Substring(BasicPrefixLength); + + var usernameAndPassword = Encoding.UTF8.GetString(Convert.FromBase64String(basicCredentials)); + var nekudataimIndex = usernameAndPassword.IndexOf(':'); + if (nekudataimIndex != -1) + { + var username = usernameAndPassword.Substring(0, nekudataimIndex); + var password = usernameAndPassword.Substring(nekudataimIndex + 1); + + if (username == _username && password == _password) + { + return true; + } + } + + return false; + } + } +} diff --git a/uhttpsharp/Handlers/SessionHandler.cs b/uhttpsharp/Handlers/SessionHandler.cs new file mode 100644 index 0000000..2871b70 --- /dev/null +++ b/uhttpsharp/Handlers/SessionHandler.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace uhttpsharp.Handlers +{ + public class SessionHandler : IHttpRequestHandler + { + private readonly Func _sessionFactory; + private readonly TimeSpan _expiration; + + private static readonly Random RandomGenerator = new Random(); + + private class SessionHolder + { + private readonly TSession _session; + private DateTime _lastAccessTime = DateTime.Now; + + public TSession Session + { + get + { + _lastAccessTime = DateTime.Now; + return _session; + } + } + + public DateTime LastAccessTime + { + get + { + return _lastAccessTime; + } + } + + public SessionHolder(TSession session) + { + _session = session; + } + } + + private readonly ConcurrentDictionary _sessions = new ConcurrentDictionary(); + + public SessionHandler(Func sessionFactory, TimeSpan expiration) + { + _sessionFactory = sessionFactory; + _expiration = expiration; + } + + public Task Handle(IHttpContext context, Func next) + { + + string sessId; + if (!context.Cookies.TryGetByName("SESSID", out sessId)) + { + sessId = RandomGenerator.Next().ToString(CultureInfo.InvariantCulture); + context.Cookies.Upsert("SESSID", sessId); + } + + var sessionHolder = _sessions.GetOrAdd(sessId, CreateSession); + + if (DateTime.Now - sessionHolder.LastAccessTime > _expiration) + { + sessionHolder = CreateSession(sessId); + _sessions.AddOrUpdate(sessId, sessionHolder, (sessionId, oldSession) => sessionHolder); + } + + context.State.Session = sessionHolder.Session; + + return next(); + } + private SessionHolder CreateSession(string sessionId) + { + return new SessionHolder(_sessionFactory()); + } + } +} diff --git a/uhttpsharp/HttpResponse.cs b/uhttpsharp/HttpResponse.cs index 5bc154a..ec280ae 100644 --- a/uhttpsharp/HttpResponse.cs +++ b/uhttpsharp/HttpResponse.cs @@ -133,15 +133,21 @@ public StringHttpResponse(string body, HttpResponseCode code, IHttpHeaders heade _body = body; } - public static IHttpResponse Create(string body, HttpResponseCode code = HttpResponseCode.Ok, string contentType = "text/html; charset=utf-8", bool keepAlive = true) + public static IHttpResponse Create(string body, HttpResponseCode code = HttpResponseCode.Ok, string contentType = "text/html; charset=utf-8", bool keepAlive = true, IHttpHeaders headers = null) { - return new StringHttpResponse(body, code, new ListHttpHeaders(new[] + // TODO : Add Overload + if (headers == null) + { + headers = EmptyHttpHeaders.Empty; + } + + return new StringHttpResponse(body, code, new CompositeHttpHeaders(new ListHttpHeaders(new[] { new KeyValuePair("Date", DateTime.UtcNow.ToString("R")), new KeyValuePair("content-type", contentType), new KeyValuePair("connection", keepAlive ? "keep-alive" : "close"), new KeyValuePair("content-length", Encoding.UTF8.GetByteCount(body).ToString(CultureInfo.InvariantCulture)), - })); + }), headers)); } public async override Task WriteBody(StreamWriter writer) diff --git a/uhttpsharp/uhttpsharp.csproj b/uhttpsharp/uhttpsharp.csproj index aa5dfe1..424e233 100644 --- a/uhttpsharp/uhttpsharp.csproj +++ b/uhttpsharp/uhttpsharp.csproj @@ -62,6 +62,7 @@ + @@ -78,6 +79,7 @@ + From bd0f1e3159a16c039194cba24fc3af37c83ab761 Mon Sep 17 00:00:00 2001 From: Shani Elharrar Date: Wed, 24 Jun 2015 16:52:24 +0300 Subject: [PATCH 21/26] Fix 100% Cpu Bug --- uhttpsharp.dll.nuspec | 2 +- uhttpsharp/Clients/TcpClientAdapter.cs | 7 +++++-- uhttpsharp/RequestProviders/IStreamReader.cs | 7 +++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/uhttpsharp.dll.nuspec b/uhttpsharp.dll.nuspec index 0cb106d..db0a392 100644 --- a/uhttpsharp.dll.nuspec +++ b/uhttpsharp.dll.nuspec @@ -2,7 +2,7 @@ uHttpSharp - 0.1.6.21 + 0.1.6.22 uHttpSharp Shani Elharrar, Joe White, Hüseyin Uslu Shani Elharrar, Joe White, Hüseyin Uslu diff --git a/uhttpsharp/Clients/TcpClientAdapter.cs b/uhttpsharp/Clients/TcpClientAdapter.cs index 302e56c..7f3b444 100644 --- a/uhttpsharp/Clients/TcpClientAdapter.cs +++ b/uhttpsharp/Clients/TcpClientAdapter.cs @@ -14,12 +14,15 @@ public TcpClientAdapter(TcpClient client) _client = client; _stream = _client.GetStream(); - // The next lines are commented out because they caused exceptions, And i'm not sure why it has been added in the first place. + // The next lines are commented out because they caused exceptions, + // They have been added because .net doesn't allow me to wait for data (ReadAsyncBlock). + // Instead, I've added Task.Delay in MyStreamReader.ReadBuffer when + // Read returns without data. + // See https://github.com/Code-Sharp/uHttpSharp/issues/14 // Read Timeout of one second. // _stream.ReadTimeout = 1000; - } public Stream Stream diff --git a/uhttpsharp/RequestProviders/IStreamReader.cs b/uhttpsharp/RequestProviders/IStreamReader.cs index f83abca..9fb3a82 100644 --- a/uhttpsharp/RequestProviders/IStreamReader.cs +++ b/uhttpsharp/RequestProviders/IStreamReader.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.IO; using System.Text; using System.Threading.Tasks; @@ -62,6 +63,12 @@ private async Task ReadBuffer() do { _count = await _underlyingStream.ReadAsync(_middleBuffer, 0, BufferSize).ConfigureAwait(false); + + if (_count == 0) + { + // Fix for 100% CPU + await Task.Delay(100).ConfigureAwait(false); + } } while (_count == 0); From 0adc4a2edc400b60d604f17c1bddb1d8df9c3b05 Mon Sep 17 00:00:00 2001 From: Jakub Kolasa Date: Wed, 17 Jan 2018 18:20:50 +0100 Subject: [PATCH 22/26] - fix newline ending in http protocol for non-windows platforms --- uhttpsharp/HttpClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uhttpsharp/HttpClient.cs b/uhttpsharp/HttpClient.cs index 3bbab9b..120a436 100644 --- a/uhttpsharp/HttpClient.cs +++ b/uhttpsharp/HttpClient.cs @@ -89,7 +89,7 @@ private async void Process() if (context.Response != null) { var streamWriter = new StreamWriter(limitedStream) { AutoFlush = false }; - + streamWriter.NewLine = "\r\n"; await WriteResponse(context, streamWriter).ConfigureAwait(false); await limitedStream.ExplicitFlushAsync().ConfigureAwait(false); From c8166a86ef4bb0acf445fffbeda59d7ffb7f6bc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20V=C3=A1zquez=20=28Dagger=29?= Date: Wed, 25 Apr 2018 14:04:40 +0200 Subject: [PATCH 23/26] Added disposable for HTTPListener (#21) --- uhttpsharp/Listeners/IHttpListener.cs | 7 ++++--- uhttpsharp/Listeners/SslListenerDecoerator.cs | 7 ++++++- uhttpsharp/Listeners/TcpListenerAdapter.cs | 5 +++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/uhttpsharp/Listeners/IHttpListener.cs b/uhttpsharp/Listeners/IHttpListener.cs index 6503765..621c553 100644 --- a/uhttpsharp/Listeners/IHttpListener.cs +++ b/uhttpsharp/Listeners/IHttpListener.cs @@ -1,12 +1,13 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using uhttpsharp.Clients; namespace uhttpsharp.Listeners { - public interface IHttpListener + public interface IHttpListener: IDisposable { Task GetClient(); } -} +} \ No newline at end of file diff --git a/uhttpsharp/Listeners/SslListenerDecoerator.cs b/uhttpsharp/Listeners/SslListenerDecoerator.cs index 8da27f9..ec8b4cd 100644 --- a/uhttpsharp/Listeners/SslListenerDecoerator.cs +++ b/uhttpsharp/Listeners/SslListenerDecoerator.cs @@ -19,5 +19,10 @@ public async Task GetClient() { return new ClientSslDecorator(await _child.GetClient().ConfigureAwait(false), _certificate); } + + public void Dispose() + { + _child.Dispose(); + } } -} \ No newline at end of file +} diff --git a/uhttpsharp/Listeners/TcpListenerAdapter.cs b/uhttpsharp/Listeners/TcpListenerAdapter.cs index db68923..ebc6980 100644 --- a/uhttpsharp/Listeners/TcpListenerAdapter.cs +++ b/uhttpsharp/Listeners/TcpListenerAdapter.cs @@ -17,5 +17,10 @@ public async Task GetClient() { return new TcpClientAdapter(await _listener.AcceptTcpClientAsync().ConfigureAwait(false)); } + + public void Dispose() + { + _listener.Stop(); + } } } \ No newline at end of file From f44cc766af490387fafc568a566a137e2418ceed Mon Sep 17 00:00:00 2001 From: meum Date: Fri, 5 Oct 2018 11:08:32 +0200 Subject: [PATCH 24/26] Make AuthenticateAsServer async --- uhttpsharp/Clients/ClientSslDecoerator.cs | 16 ++++++++++++++-- uhttpsharp/HttpClient.cs | 16 +++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/uhttpsharp/Clients/ClientSslDecoerator.cs b/uhttpsharp/Clients/ClientSslDecoerator.cs index 116682b..7f3962a 100644 --- a/uhttpsharp/Clients/ClientSslDecoerator.cs +++ b/uhttpsharp/Clients/ClientSslDecoerator.cs @@ -1,21 +1,33 @@ -using System.IO; +using System; +using System.IO; using System.Net; using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; +using System.Threading.Tasks; namespace uhttpsharp.Clients { public class ClientSslDecorator : IClient { private readonly IClient _child; + private readonly X509Certificate _certificate; private readonly SslStream _sslStream; public ClientSslDecorator(IClient child, X509Certificate certificate) { _child = child; + _certificate = certificate; _sslStream = new SslStream(_child.Stream); - _sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Tls, true); + } + + public async Task AuthenticateAsServer() + { + Task timeout = Task.Delay(TimeSpan.FromSeconds(10)); + if (timeout == await Task.WhenAny(_sslStream.AuthenticateAsServerAsync(_certificate, false, SslProtocols.Tls, true), timeout).ConfigureAwait(false)) + { + throw new TimeoutException("SSL Authentication Timeout"); + } } public Stream Stream diff --git a/uhttpsharp/HttpClient.cs b/uhttpsharp/HttpClient.cs index 120a436..8b9b358 100644 --- a/uhttpsharp/HttpClient.cs +++ b/uhttpsharp/HttpClient.cs @@ -44,7 +44,7 @@ internal sealed class HttpClientHandler private readonly IHttpRequestProvider _requestProvider; private readonly EndPoint _remoteEndPoint; private DateTime _lastOperationTime; - private readonly Stream _stream; + private Stream _stream; public HttpClientHandler(IClient client, Func requestHandler, IHttpRequestProvider requestProvider) { @@ -52,8 +52,6 @@ public HttpClientHandler(IClient client, Func requestHandler _client = client; _requestHandler = requestHandler; _requestProvider = requestProvider; - - _stream = new BufferedStream(_client.Stream, 8096); Logger.InfoFormat("Got Client {0}", _remoteEndPoint); @@ -62,10 +60,22 @@ public HttpClientHandler(IClient client, Func requestHandler UpdateLastOperationTime(); } + private async Task InitializeStream() + { + if (Client is ClientSslDecorator) + { + await ((ClientSslDecorator)Client).AuthenticateAsServer(); + } + + _stream = new BufferedStream(_client.Stream, 8096); + } + private async void Process() { try { + await InitializeStream(); + while (_client.Connected) { // TODO : Configuration. From 819b1b422fe1b8d5e6ba885a49c266fd0f5dfa4f Mon Sep 17 00:00:00 2001 From: meum Date: Fri, 5 Oct 2018 16:17:44 +0200 Subject: [PATCH 25/26] ConfigureAwait(false) --- uhttpsharp/HttpClient.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uhttpsharp/HttpClient.cs b/uhttpsharp/HttpClient.cs index 8b9b358..9adadb0 100644 --- a/uhttpsharp/HttpClient.cs +++ b/uhttpsharp/HttpClient.cs @@ -64,7 +64,7 @@ private async Task InitializeStream() { if (Client is ClientSslDecorator) { - await ((ClientSslDecorator)Client).AuthenticateAsServer(); + await ((ClientSslDecorator)Client).AuthenticateAsServer().ConfigureAwait(false); } _stream = new BufferedStream(_client.Stream, 8096); @@ -290,4 +290,4 @@ private static Func Aggregate(this IList Date: Wed, 2 Dec 2020 02:44:08 +1300 Subject: [PATCH 26/26] Bumped TLS version to 1.2 --- uhttpsharp/Clients/ClientSslDecoerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uhttpsharp/Clients/ClientSslDecoerator.cs b/uhttpsharp/Clients/ClientSslDecoerator.cs index 7f3962a..98eff9a 100644 --- a/uhttpsharp/Clients/ClientSslDecoerator.cs +++ b/uhttpsharp/Clients/ClientSslDecoerator.cs @@ -24,7 +24,7 @@ public ClientSslDecorator(IClient child, X509Certificate certificate) public async Task AuthenticateAsServer() { Task timeout = Task.Delay(TimeSpan.FromSeconds(10)); - if (timeout == await Task.WhenAny(_sslStream.AuthenticateAsServerAsync(_certificate, false, SslProtocols.Tls, true), timeout).ConfigureAwait(false)) + if (timeout == await Task.WhenAny(_sslStream.AuthenticateAsServerAsync(_certificate, false, SslProtocols.Tls12, true), timeout).ConfigureAwait(false)) { throw new TimeoutException("SSL Authentication Timeout"); }