diff --git a/src/Microsoft.AspNet.Abstractions/HttpContext.cs b/src/Microsoft.AspNet.Abstractions/HttpContext.cs
index a933d34660..81e44240c2 100644
--- a/src/Microsoft.AspNet.Abstractions/HttpContext.cs
+++ b/src/Microsoft.AspNet.Abstractions/HttpContext.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Abstractions.Security;
@@ -21,6 +22,10 @@ namespace Microsoft.AspNet.Abstractions
public abstract IServiceProvider RequestServices { get; set; }
+ public abstract CancellationToken OnRequestAborted { get; }
+
+ public abstract void Abort();
+
public abstract void Dispose();
public abstract object GetFeature(Type type);
diff --git a/src/Microsoft.AspNet.HttpFeature/IHttpRequestLifetime.cs b/src/Microsoft.AspNet.HttpFeature/IHttpRequestLifetime.cs
new file mode 100644
index 0000000000..3ea7a0ee34
--- /dev/null
+++ b/src/Microsoft.AspNet.HttpFeature/IHttpRequestLifetime.cs
@@ -0,0 +1,10 @@
+using System.Threading;
+
+namespace Microsoft.AspNet.HttpFeature
+{
+ public interface IHttpRequestLifetime
+ {
+ CancellationToken OnRequestAborted { get; }
+ void Abort();
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.HttpFeature/Microsoft.AspNet.HttpFeature.kproj b/src/Microsoft.AspNet.HttpFeature/Microsoft.AspNet.HttpFeature.kproj
index 5f8f775ed5..96973626c9 100644
--- a/src/Microsoft.AspNet.HttpFeature/Microsoft.AspNet.HttpFeature.kproj
+++ b/src/Microsoft.AspNet.HttpFeature/Microsoft.AspNet.HttpFeature.kproj
@@ -24,6 +24,7 @@
+
diff --git a/src/Microsoft.AspNet.PipelineCore/DefaultHttpContext.cs b/src/Microsoft.AspNet.PipelineCore/DefaultHttpContext.cs
index dd114e9e8b..462e5a593e 100644
--- a/src/Microsoft.AspNet.PipelineCore/DefaultHttpContext.cs
+++ b/src/Microsoft.AspNet.PipelineCore/DefaultHttpContext.cs
@@ -2,10 +2,12 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.Abstractions.Security;
using Microsoft.AspNet.FeatureModel;
+using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.HttpFeature.Security;
using Microsoft.AspNet.PipelineCore.Infrastructure;
using Microsoft.AspNet.PipelineCore.Security;
@@ -20,6 +22,7 @@ namespace Microsoft.AspNet.PipelineCore
private FeatureReference _canHasItems;
private FeatureReference _canHasServiceProviders;
private FeatureReference _authentication;
+ private FeatureReference _lifetime;
private IFeatureCollection _features;
public DefaultHttpContext(IFeatureCollection features)
@@ -48,6 +51,11 @@ namespace Microsoft.AspNet.PipelineCore
get { return _authentication.Fetch(_features) ?? _authentication.Update(_features, new DefaultHttpAuthentication()); }
}
+ private IHttpRequestLifetime Lifetime
+ {
+ get { return _lifetime.Fetch(_features); }
+ }
+
public override HttpRequest Request { get { return _request; } }
public override HttpResponse Response { get { return _response; } }
@@ -86,6 +94,28 @@ namespace Microsoft.AspNet.PipelineCore
public int Revision { get { return _features.Revision; } }
+ public override CancellationToken OnRequestAborted
+ {
+ get
+ {
+ var lifetime = Lifetime;
+ if (lifetime != null)
+ {
+ return lifetime.OnRequestAborted;
+ }
+ return CancellationToken.None;
+ }
+ }
+
+ public override void Abort()
+ {
+ var lifetime = Lifetime;
+ if (lifetime != null)
+ {
+ lifetime.Abort();
+ }
+ }
+
public override void Dispose()
{
// REVIEW: is this necessary? is the environment "owned" by the context?
diff --git a/test/Microsoft.AspNet.Owin.Tests/OwinEnvironmentTests.cs b/test/Microsoft.AspNet.Owin.Tests/OwinEnvironmentTests.cs
index de9fc4a4a6..e84926c2f6 100644
--- a/test/Microsoft.AspNet.Owin.Tests/OwinEnvironmentTests.cs
+++ b/test/Microsoft.AspNet.Owin.Tests/OwinEnvironmentTests.cs
@@ -104,6 +104,16 @@ namespace Microsoft.AspNet.Owin
{
throw new NotImplementedException();
}
+
+ public override CancellationToken OnRequestAborted
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public override void Abort()
+ {
+ throw new NotImplementedException();
+ }
}
private class MoqHttpRequest : HttpRequest, IHttpRequestInformation