diff --git a/samples/SelfHostServer/SelfHostServer.kproj b/samples/SelfHostServer/SelfHostServer.kproj index 2695c3ae40..003e2613c1 100644 --- a/samples/SelfHostServer/SelfHostServer.kproj +++ b/samples/SelfHostServer/SelfHostServer.kproj @@ -1,4 +1,4 @@ - + 14.0 @@ -7,11 +7,22 @@ 1236f93a-ac5c-4a77-9477-c88f040151ca + + ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ 2.0 + + SelfHostServer + + + 2.0 + 59517 + + web + diff --git a/samples/SelfHostServer/Startup.cs b/samples/SelfHostServer/Startup.cs index ac29316bd5..fae50ab407 100644 --- a/samples/SelfHostServer/Startup.cs +++ b/samples/SelfHostServer/Startup.cs @@ -35,7 +35,7 @@ namespace SelfHostServer var info = (ServerInformation)app.Server; info.Listener.AuthenticationManager.AuthenticationTypes = AuthenticationTypes.AllowAnonymous; - loggerfactory.AddConsole(); + loggerfactory.AddConsole(LogLevel.Verbose); app.Run(async context => { diff --git a/samples/SelfHostServer/project.json b/samples/SelfHostServer/project.json index ffc11cd083..aded313626 100644 --- a/samples/SelfHostServer/project.json +++ b/samples/SelfHostServer/project.json @@ -1,4 +1,5 @@ { + "webroot": "wwwroot", "dependencies": { "Microsoft.AspNet.Hosting": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/HeadersLogStructure.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/HeadersLogStructure.cs new file mode 100644 index 0000000000..26c182df2a --- /dev/null +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/HeadersLogStructure.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Open Technologies, Inc. +// All Rights Reserved +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING +// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF +// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR +// NON-INFRINGEMENT. +// See the Apache 2 License for the specific language governing +// permissions and limitations under the License. + +using System.Collections; + +namespace Microsoft.Net.Http.Server +{ + internal class HeadersLogStructure : IEnumerable + { + private readonly HeaderCollection _headers; + + internal HeadersLogStructure(HeaderCollection headers) + { + _headers = headers; + } + + IEnumerator IEnumerable.GetEnumerator() + { + foreach (var header in _headers) + { + foreach (var value in header.Value) + { + yield return header.Key + ": " + value; + } + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/Request.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/Request.cs index 750d4425d3..bee0c09df9 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/Request.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/Request.cs @@ -22,6 +22,7 @@ //------------------------------------------------------------------------------ using System; +using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -29,11 +30,10 @@ using System.Net; using System.Runtime.InteropServices; using System.Security.Claims; using System.Security.Cryptography.X509Certificates; -#if !ASPNETCORE50 -using System.Security.Principal; -#endif +using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.Framework.Logging; namespace Microsoft.Net.Http.Server { @@ -72,7 +72,7 @@ namespace Microsoft.Net.Http.Server private ClaimsPrincipal _user; private bool _isDisposed = false; - + internal unsafe Request(RequestContext httpContext, NativeRequestContext memoryBlob) { // TODO: Verbose log @@ -147,7 +147,10 @@ namespace Microsoft.Net.Http.Server // TODO: Verbose log parameters - // TODO: Verbose log headers + if (_requestContext.Logger.IsEnabled(LogLevel.Verbose)) + { + RequestContext.Logger.WriteVerbose(new ReceiveRequestLogContext(this)); + } } internal SslStatus SslStatus @@ -510,5 +513,51 @@ namespace Microsoft.Net.Http.Server _nativeStream = new RequestStream(RequestContext); } } + + private class ReceiveRequestLogContext : LoggerStructureBase + { + private readonly Request _request; + + internal ReceiveRequestLogContext(Request request) + { + _request = request; + Message = "Received Request"; + } + + public string Method { get { return _request.Method; } } + public string PathBase { get { return _request.PathBase; } } + public string Path { get { return _request.Path; } } + public string Query { get { return _request.QueryString; } } + public string Protocol { get { return "HTTP/" + _request.ProtocolVersion.ToString(2); } } + public IEnumerable Headers { get { return new HeadersLogStructure(_request.Headers); } } + + public override string Format() + { + var requestBuilder = new StringBuilder("Received request: "); + + // GET /path?query HTTP/1.1 + requestBuilder.Append(Method); + requestBuilder.Append(" "); + requestBuilder.Append(PathBase); + requestBuilder.Append(Path); + requestBuilder.Append(Query); + requestBuilder.Append(" "); + requestBuilder.Append(Protocol); + requestBuilder.Append("; Headers: { "); + + foreach (var header in _request.Headers) + { + foreach (var value in header.Value) + { + requestBuilder.Append(header.Key); + requestBuilder.Append(": "); + requestBuilder.Append(value); + requestBuilder.Append("; "); + } + } + requestBuilder.Append("}"); + return requestBuilder.ToString(); + } + } } } diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/Response.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/Response.cs index 21149425af..c1a3c7b373 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/Response.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/Response.cs @@ -22,14 +22,17 @@ //------------------------------------------------------------------------------ using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.InteropServices; +using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.Framework.Logging; namespace Microsoft.Net.Http.Server { @@ -358,9 +361,13 @@ namespace Microsoft.Net.Http.Server { Debug.Assert(!HeadersSent, "HttpListenerResponse::SendHeaders()|SentHeaders is true."); - // TODO: Verbose log headers _responseState = ResponseState.SentHeaders; - string reasonPhrase = GetReasonPhrase(_nativeResponse.Response_V1.StatusCode); + var reasonPhrase = GetReasonPhrase(StatusCode); + + if (RequestContext.Logger.IsEnabled(LogLevel.Verbose)) + { + RequestContext.Logger.WriteVerbose(new SendResponseLogContext(this)); + } /* if (m_BoundaryType==BoundaryType.Raw) { @@ -837,5 +844,46 @@ namespace Microsoft.Net.Http.Server actionPair.Item1(actionPair.Item2); } } + + private class SendResponseLogContext : LoggerStructureBase + { + private readonly Response _response; + + internal SendResponseLogContext(Response response) + { + _response = response; + Message = "Sending Response"; + } + + public string Protocol { get { return "HTTP/1.1"; } } // HTTP.SYS only allows 1.1 responses. + public string StatusCode { get { return _response.StatusCode.ToString(CultureInfo.InvariantCulture); } } + public string ReasonPhrase { get { return _response.ReasonPhrase ?? _response.GetReasonPhrase(_response.StatusCode); } } + public IEnumerable Headers { get { return new HeadersLogStructure(_response.Headers); } } + + public override string Format() + { + // HTTP/1.1 200 OK + var responseBuilder = new StringBuilder("Sending Response: "); + responseBuilder.Append(Protocol); + responseBuilder.Append(" "); + responseBuilder.Append(StatusCode); + responseBuilder.Append(" "); + responseBuilder.Append(ReasonPhrase); + responseBuilder.Append("; Headers: { "); + + foreach (var header in _response.Headers) + { + foreach (var value in header.Value) + { + responseBuilder.Append(header.Key); + responseBuilder.Append(": "); + responseBuilder.Append(value); + responseBuilder.Append("; "); + } + } + responseBuilder.Append("}"); + return responseBuilder.ToString(); + } + } } }