diff --git a/src/Microsoft.AspNet.Http.Interfaces/IRequestIdentifierFeature.cs b/src/Microsoft.AspNet.Http.Interfaces/IRequestIdentifierFeature.cs new file mode 100644 index 00000000..642dca12 --- /dev/null +++ b/src/Microsoft.AspNet.Http.Interfaces/IRequestIdentifierFeature.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Http.Interfaces +{ + /// + /// Feature to identify a request. + /// + public interface IRequestIdentifierFeature + { + /// + /// Identifier to trace a request. + /// + Guid TraceIdentifier { get; } + } +} diff --git a/src/Microsoft.AspNet.Owin/OwinConstants.cs b/src/Microsoft.AspNet.Owin/OwinConstants.cs index b86dfc1a..98ed1c42 100644 --- a/src/Microsoft.AspNet.Owin/OwinConstants.cs +++ b/src/Microsoft.AspNet.Owin/OwinConstants.cs @@ -20,6 +20,14 @@ internal static class OwinConstants #endregion + #region OWIN v1.1.0 - 3.2.1 Request Data + + // OWIN 1.1.0 http://owin.org/html/owin.html + + public const string RequestId = "owin.RequestId"; + + #endregion + #region OWIN v1.0.0 - 3.2.2. Response Data // http://owin.org/spec/owin-1.0.0.html diff --git a/src/Microsoft.AspNet.Owin/OwinEnvironment.cs b/src/Microsoft.AspNet.Owin/OwinEnvironment.cs index f64f2743..7e17a7d1 100644 --- a/src/Microsoft.AspNet.Owin/OwinEnvironment.cs +++ b/src/Microsoft.AspNet.Owin/OwinEnvironment.cs @@ -80,7 +80,7 @@ public OwinEnvironment(HttpContext context) { OwinConstants.Security.User, new FeatureMap(feature => feature.User, ()=> null, (feature, value) => feature.User = Utilities.MakeClaimsPrincipal((IPrincipal)value), () => new HttpAuthenticationFeature()) - }, + } }; // owin.CallCancelled is required but the feature may not be present. @@ -113,6 +113,9 @@ public OwinEnvironment(HttpContext context) } _context.Items[typeof(HttpContext).FullName] = _context; // Store for lookup when we transition back out of OWIN + + // The request identifier is a string per the spec. + _entries[OwinConstants.RequestId] = new FeatureMap(feature => feature.TraceIdentifier.ToString()); } // Public in case there's a new/custom feature interface that needs to be added. @@ -369,7 +372,7 @@ public FeatureMap(Func getter, Action setter } public FeatureMap(Func getter, Func defaultFactory, Action setter) - : base(typeof(TFeature), feature => getter((TFeature)feature), defaultFactory,(feature, value) => setter((TFeature)feature, value)) + : base(typeof(TFeature), feature => getter((TFeature)feature), defaultFactory, (feature, value) => setter((TFeature)feature, value)) { } diff --git a/src/Microsoft.AspNet.Owin/OwinFeatureCollection.cs b/src/Microsoft.AspNet.Owin/OwinFeatureCollection.cs index 11d5892c..af443bcc 100644 --- a/src/Microsoft.AspNet.Owin/OwinFeatureCollection.cs +++ b/src/Microsoft.AspNet.Owin/OwinFeatureCollection.cs @@ -32,7 +32,8 @@ public class OwinFeatureCollection : IHttpRequestLifetimeFeature, IHttpAuthenticationFeature, IHttpWebSocketFeature, - IOwinEnvironmentFeature + IOwinEnvironmentFeature, + IRequestIdentifierFeature { public IDictionary Environment { get; set; } private bool _headersSent; @@ -427,6 +428,22 @@ public bool IsReadOnly get { return true; } } + Guid IRequestIdentifierFeature.TraceIdentifier + { + get + { + var requestId = Prop(OwinConstants.RequestId); + Guid requestIdentifier; + + if (requestId != null && Guid.TryParse(requestId, out requestIdentifier)) + { + return requestIdentifier; + } + + return Guid.Empty; + } + } + public bool Remove(KeyValuePair item) { throw new NotSupportedException();