diff --git a/src/DemoControllers/DemoControllers.csproj b/src/DemoControllers/DemoControllers.csproj
index bc1a4d9..49ff56e 100644
--- a/src/DemoControllers/DemoControllers.csproj
+++ b/src/DemoControllers/DemoControllers.csproj
@@ -123,6 +123,10 @@
+
+ {06A3D120-5923-4AD1-8411-7395A1EC6E94}
+ WebServer.Logging
+
{0B20D095-2896-41A6-865D-172DFD5ECC99}
Webserver.Models
diff --git a/src/DemoControllers/FromContentControllerSample.cs b/src/DemoControllers/FromContentControllerSample.cs
index ac592b5..15d0e06 100644
--- a/src/DemoControllers/FromContentControllerSample.cs
+++ b/src/DemoControllers/FromContentControllerSample.cs
@@ -1,33 +1,40 @@
using Restup.DemoControllers.Model;
+using Restup.Webserver;
using Restup.Webserver.Attributes;
using Restup.Webserver.Models.Contracts;
using Restup.Webserver.Models.Schemas;
-using System;
-using System.Diagnostics;
+using Restup.WebServer.Logging;
namespace Restup.DemoControllers
{
[RestController(InstanceCreationType.PerCall)]
public sealed class FromContentControllerSample
{
+ private readonly ILogger _log;
+
+ public FromContentControllerSample()
+ {
+ _log = LogManager.GetLogger();
+ }
+
[UriFormat("/fromcontent")]
public IPutResponse UpdateSomething([FromContent] FromContentData data)
{
- Debug.WriteLine($"Received counter value of {data.Counter}");
+ _log.Debug($"Received counter value of {data.Counter}");
return new PutResponse(PutResponse.ResponseStatus.OK);
}
[UriFormat("/fromcontent")]
public IPostResponse CreateSomething([FromContent] FromContentData data)
{
- Debug.WriteLine($"Received counter value of {data.Counter}");
+ _log.Debug($"Received counter value of {data.Counter}");
return new PostResponse(PostResponse.ResponseStatus.Created, $"fromcontent/{data.Counter}");
}
[UriFormat("/stringencoding")]
public IGetResponse EncodingDecodingTest([FromContent] MoreComplexData data)
{
- Debug.WriteLine($"Received complex data with text {data.Text}");
+ _log.Debug($"Received complex data with text {data.Text}");
return new GetResponse(GetResponse.ResponseStatus.OK, new MoreComplexData() { Text = data.Text });
}
}
diff --git a/src/HttpMessage/ServerRequestParsers/HttpRequestParser.cs b/src/HttpMessage/ServerRequestParsers/HttpRequestParser.cs
index 6b57ff0..1c6af74 100644
--- a/src/HttpMessage/ServerRequestParsers/HttpRequestParser.cs
+++ b/src/HttpMessage/ServerRequestParsers/HttpRequestParser.cs
@@ -37,51 +37,44 @@ internal async Task ParseRequestStream(IInputStream re
var httpStream = new HttpRequestStream(requestStream);
var request = new MutableHttpServerRequest();
- try
+ var stream = await httpStream.ReadAsync(BUFFER_SIZE, InputStreamOptions.Partial);
+ byte[] streamData = stream.Data;
+
+ var requestPipeline = GetPipeline();
+ using (var pipeLineEnumerator = requestPipeline.GetEnumerator())
{
- var stream = await httpStream.ReadAsync(BUFFER_SIZE, InputStreamOptions.Partial);
- byte[] streamData = stream.Data;
+ pipeLineEnumerator.MoveNext();
+ bool requestComplete = false;
- var requestPipeline = GetPipeline();
- using (var pipeLineEnumerator = requestPipeline.GetEnumerator())
+ while (!requestComplete)
{
- pipeLineEnumerator.MoveNext();
- bool requestComplete = false;
+ pipeLineEnumerator.Current.HandleRequestPart(streamData, request);
+ streamData = pipeLineEnumerator.Current.UnparsedData;
- while (!requestComplete)
+ if (pipeLineEnumerator.Current.IsFinished)
{
- pipeLineEnumerator.Current.HandleRequestPart(streamData, request);
- streamData = pipeLineEnumerator.Current.UnparsedData;
-
- if (pipeLineEnumerator.Current.IsFinished)
+ if (!pipeLineEnumerator.Current.IsSucceeded ||
+ !pipeLineEnumerator.MoveNext())
{
- if (!pipeLineEnumerator.Current.IsSucceeded ||
- !pipeLineEnumerator.MoveNext())
- {
- break;
- }
+ break;
}
- else
- {
- var newStreamdata = await httpStream.ReadAsync(BUFFER_SIZE, InputStreamOptions.Partial);
-
- if (!newStreamdata.ReadSuccessful)
- {
- break;
- }
+ }
+ else
+ {
+ var newStreamdata = await httpStream.ReadAsync(BUFFER_SIZE, InputStreamOptions.Partial);
- streamData = streamData.ConcatArray(newStreamdata.Data);
+ if (!newStreamdata.ReadSuccessful)
+ {
+ break;
}
+
+ streamData = streamData.ConcatArray(newStreamdata.Data);
}
}
-
- request.IsComplete = requestPipeline.All(p => p.IsSucceeded);
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex.Message);
}
+ request.IsComplete = requestPipeline.All(p => p.IsSucceeded);
+
return request;
}
}
diff --git a/src/Restup.sln b/src/Restup.sln
index 331ac33..3878207 100644
--- a/src/Restup.sln
+++ b/src/Restup.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.24720.0
+VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Webserver", "Webserver\Webserver.csproj", "{837B8FF3-DED6-4DC7-AD58-DBB0B3E44DD4}"
EndProject
@@ -29,8 +29,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebServer.Logging", "WebSer
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
- HttpMessage\HttpMessage.projitems*{837b8ff3-ded6-4dc7-ad58-dbb0b3e44dd4}*SharedItemsImports = 4
HttpMessage\HttpMessage.projitems*{13aba022-a7c1-45b7-9e47-2bb74f2a7f9f}*SharedItemsImports = 13
+ HttpMessage\HttpMessage.projitems*{837b8ff3-ded6-4dc7-ad58-dbb0b3e44dd4}*SharedItemsImports = 4
HttpMessage\HttpMessage.projitems*{d313f525-2d90-4bf5-8857-2698ee580a65}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/src/WebServer/Http/HttpServer.cs b/src/WebServer/Http/HttpServer.cs
index 17f8448..db4a4af 100644
--- a/src/WebServer/Http/HttpServer.cs
+++ b/src/WebServer/Http/HttpServer.cs
@@ -45,16 +45,18 @@ public HttpServer(int serverPort)
public async Task StartServerAsync()
{
+ _log.Info($"Binding webserver to port {_port}...");
+
await _listener.BindServiceNameAsync(_port.ToString());
- _log.Info($"Webserver listening on port {_port}");
+ _log.Info($"Webserver listening on port {_port}.");
}
public void StopServer()
{
((IDisposable)this).Dispose();
- _log.Info($"Webserver stopped listening on port {_port}");
+ _log.Info($"Webserver stopped listening on port {_port}.");
}
private async void ProcessRequestAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
@@ -66,14 +68,28 @@ await Task.Run(async () =>
using (var inputStream = args.Socket.InputStream)
{
var request = await MutableHttpServerRequest.Parse(inputStream);
+ if (!request.IsComplete)
+ {
+ _log.Warn($"Request {request.Method} {request.Uri} aborted.");
+ return;
+ }
+
+ if (_log.IsDebugEnabled())
+ _log.Debug($"Handling request {request.Method} {request.Uri} from {args.Socket.Information.LocalAddress}.");
+
var httpResponse = await HandleRequestAsync(request);
+ if (_log.IsDebugEnabled())
+ _log.Debug($"Request {request.Method} {request.Uri} from {args.Socket.Information.LocalAddress} handled, response status: {httpResponse.ResponseStatus}.");
+
await WriteResponseAsync(httpResponse, args.Socket);
+ if (_log.IsDebugEnabled())
+ _log.Debug($"Responded to request {request.Method} {request.Uri}, {args.Socket.Information.LocalAddress}.");
}
}
catch (Exception ex)
{
- _log.Error($"Exception while handling process: {ex.Message}");
+ _log.Error($"Exception while handling request from {args.Socket.Information.LocalAddress}", ex);
}
finally
{
@@ -168,7 +184,9 @@ private static async Task WriteResponseAsync(HttpServerResponse response, Stream
void IDisposable.Dispose()
{
+ _log.Info("Disposing HttpServer...");
_listener.Dispose();
+ _log.Info("HttpServer disposed.");
}
}
}
diff --git a/src/WebServer/LogManager.cs b/src/WebServer/LogManager.cs
index 908ead7..65b221c 100644
--- a/src/WebServer/LogManager.cs
+++ b/src/WebServer/LogManager.cs
@@ -10,7 +10,7 @@ public static class LogManager
static LogManager()
{
- _logFactory = new NullLogFactory();
+ _logFactory = new DebugLogFactory();
}
public static ILogger GetLogger()
@@ -28,40 +28,47 @@ public static void SetLogFactory(ILogFactory logFactory)
Interlocked.Exchange(ref _logFactory, logFactory);
}
- private class NullLogFactory : ILogFactory
+ private class DebugLogFactory : ILogFactory
{
- private readonly NullLogger _nullLogger;
+ private ILogger _debugLogger;
- public NullLogFactory()
+ public DebugLogFactory()
{
- _nullLogger = new NullLogger();
+ _debugLogger = new DebugLogger();
}
- ILogger ILogFactory.GetLogger()
+ public void Dispose()
{
- return _nullLogger;
+ _debugLogger = null;
}
ILogger ILogFactory.GetLogger(string name)
{
- return _nullLogger;
+ return _debugLogger;
}
- public void Dispose()
+ ILogger ILogFactory.GetLogger()
{
+ return _debugLogger;
}
}
- private class NullLogger : AbstractLogger
+ public class DebugLogger : AbstractLogger
{
- protected override bool IsLogEnabled(LogLevel trace) => false;
-
- protected override void LogMessage(string message, LogLevel loggingLevel, params object[] args)
+ protected override bool IsLogEnabled(LogLevel trace)
{
+ // Ignore level, log everything
+ return true;
}
protected override void LogMessage(string message, LogLevel loggingLevel, Exception ex)
{
+ System.Diagnostics.Debug.WriteLine($"{DateTime.UtcNow.ToString("dd-MM-yyyy hh:mm:ss.fff")} {loggingLevel}: {message}. Exception: {Environment.NewLine} {ex}");
+ }
+
+ protected override void LogMessage(string message, LogLevel loggingLevel, params object[] args)
+ {
+ System.Diagnostics.Debug.WriteLine($"{DateTime.UtcNow.ToString("dd-MM-yyyy hh:mm:ss.fff")} {loggingLevel}: {(string.Format(message, args))}");
}
}
}