diff --git a/.gitignore b/.gitignore
index 2554a1fc23..8bc217058d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,5 @@ nuget.exe
*.userprefs
*DS_Store
*.ncrunchsolution
+*.*sdf
+*.ipch
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Abstractions/HttpResponse.cs b/src/Microsoft.AspNet.Abstractions/HttpResponse.cs
index de84899fda..8df6277482 100644
--- a/src/Microsoft.AspNet.Abstractions/HttpResponse.cs
+++ b/src/Microsoft.AspNet.Abstractions/HttpResponse.cs
@@ -15,6 +15,7 @@ namespace Microsoft.AspNet.Abstractions
public abstract long? ContentLength { get; set; }
public abstract string ContentType { get; set; }
+ public abstract IResponseCookiesCollection Cookies { get; }
public abstract Task WriteAsync(string data);
}
}
diff --git a/src/Microsoft.AspNet.Abstractions/IResponseCookiesCollection.cs b/src/Microsoft.AspNet.Abstractions/IResponseCookiesCollection.cs
new file mode 100644
index 0000000000..8e38bb92dd
--- /dev/null
+++ b/src/Microsoft.AspNet.Abstractions/IResponseCookiesCollection.cs
@@ -0,0 +1,37 @@
+
+namespace Microsoft.AspNet.Abstractions
+{
+ ///
+ /// A wrapper for the response Set-Cookie header
+ ///
+ public interface IResponseCookiesCollection
+ {
+ ///
+ /// Add a new cookie and value
+ ///
+ ///
+ ///
+ void Append(string key, string value);
+
+ ///
+ /// Add a new cookie
+ ///
+ ///
+ ///
+ ///
+ void Append(string key, string value, CookieOptions options);
+
+ ///
+ /// Sets an expired cookie
+ ///
+ ///
+ void Delete(string key);
+
+ ///
+ /// Sets an expired cookie
+ ///
+ ///
+ ///
+ void Delete(string key, CookieOptions options);
+ }
+}
diff --git a/src/Microsoft.AspNet.PipelineCore/Collections/RequestCookieCollection.cs b/src/Microsoft.AspNet.PipelineCore/Collections/RequestCookieCollection.cs
deleted file mode 100644
index 91b1577f28..0000000000
--- a/src/Microsoft.AspNet.PipelineCore/Collections/RequestCookieCollection.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Microsoft.AspNet.PipelineCore.Collections
-{
- ///
- /// A wrapper for the request Cookie header
- ///
- public class RequestCookieCollection : IEnumerable>
- {
- ///
- /// Create a new wrapper
- ///
- ///
- public RequestCookieCollection(IDictionary store)
- {
- if (store == null)
- {
- throw new ArgumentNullException("store");
- }
-
- Store = store;
- }
-
- private IDictionary Store { get; set; }
-
- ///
- /// Returns null rather than throwing KeyNotFoundException
- ///
- ///
- ///
- public string this[string key]
- {
- get
- {
- string value;
- Store.TryGetValue(key, out value);
- return value;
- }
- }
-
- ///
- ///
- ///
- ///
- public IEnumerator> GetEnumerator()
- {
- return Store.GetEnumerator();
- }
-
- ///
- ///
- ///
- ///
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- }
-}
diff --git a/src/Microsoft.AspNet.PipelineCore/RequestCookiesCollection.cs b/src/Microsoft.AspNet.PipelineCore/Collections/RequestCookiesCollection.cs
similarity index 97%
rename from src/Microsoft.AspNet.PipelineCore/RequestCookiesCollection.cs
rename to src/Microsoft.AspNet.PipelineCore/Collections/RequestCookiesCollection.cs
index 0f84ea704f..40445bb31d 100644
--- a/src/Microsoft.AspNet.PipelineCore/RequestCookiesCollection.cs
+++ b/src/Microsoft.AspNet.PipelineCore/Collections/RequestCookiesCollection.cs
@@ -4,7 +4,7 @@ using System.Collections.Generic;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.PipelineCore.Infrastructure;
-namespace Microsoft.AspNet.PipelineCore
+namespace Microsoft.AspNet.PipelineCore.Collections
{
public class RequestCookiesCollection : IReadableStringCollection
{
diff --git a/src/Microsoft.AspNet.PipelineCore/Collections/ResponseCookieCollection.cs b/src/Microsoft.AspNet.PipelineCore/Collections/ResponseCookiesCollection.cs
similarity index 96%
rename from src/Microsoft.AspNet.PipelineCore/Collections/ResponseCookieCollection.cs
rename to src/Microsoft.AspNet.PipelineCore/Collections/ResponseCookiesCollection.cs
index 78703285cf..1a11469597 100644
--- a/src/Microsoft.AspNet.PipelineCore/Collections/ResponseCookieCollection.cs
+++ b/src/Microsoft.AspNet.PipelineCore/Collections/ResponseCookiesCollection.cs
@@ -3,20 +3,19 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.AspNet.Abstractions.Infrastructure;
-using Microsoft.AspNet.Abstractions;
-namespace Microsoft.AspNet.PipelineCore.Collections
+namespace Microsoft.AspNet.Abstractions.Collections
{
///
/// A wrapper for the response Set-Cookie header
///
- public class ResponseCookieCollection
+ public class ResponseCookiesCollection : IResponseCookiesCollection
{
///
/// Create a new wrapper
///
///
- public ResponseCookieCollection(IHeaderDictionary headers)
+ public ResponseCookiesCollection(IHeaderDictionary headers)
{
if (headers == null)
{
diff --git a/src/Microsoft.AspNet.PipelineCore/DefaultCanHasRequestCookies.cs b/src/Microsoft.AspNet.PipelineCore/DefaultCanHasRequestCookies.cs
index df33085763..b6071c4d41 100644
--- a/src/Microsoft.AspNet.PipelineCore/DefaultCanHasRequestCookies.cs
+++ b/src/Microsoft.AspNet.PipelineCore/DefaultCanHasRequestCookies.cs
@@ -1,7 +1,9 @@
using System;
using Microsoft.AspNet.Abstractions;
+using Microsoft.AspNet.Abstractions.Infrastructure;
using Microsoft.AspNet.FeatureModel;
using Microsoft.AspNet.HttpFeature;
+using Microsoft.AspNet.PipelineCore.Collections;
using Microsoft.AspNet.PipelineCore.Infrastructure;
namespace Microsoft.AspNet.PipelineCore
@@ -24,7 +26,7 @@ namespace Microsoft.AspNet.PipelineCore
get
{
var headers = _request.Fetch(_features).Headers;
- string cookiesHeader = ParsingHelpers.GetHeader(headers, "Cookies") ?? "";
+ string cookiesHeader = ParsingHelpers.GetHeader(headers, Constants.Headers.Cookie) ?? "";
if (_cookiesCollection == null)
{
diff --git a/src/Microsoft.AspNet.PipelineCore/DefaultCanHasResponseCookies.cs b/src/Microsoft.AspNet.PipelineCore/DefaultCanHasResponseCookies.cs
new file mode 100644
index 0000000000..ee176b7af9
--- /dev/null
+++ b/src/Microsoft.AspNet.PipelineCore/DefaultCanHasResponseCookies.cs
@@ -0,0 +1,35 @@
+using Microsoft.AspNet.Abstractions;
+using Microsoft.AspNet.Abstractions.Collections;
+using Microsoft.AspNet.FeatureModel;
+using Microsoft.AspNet.HttpFeature;
+using Microsoft.AspNet.PipelineCore.Collections;
+using Microsoft.AspNet.PipelineCore.Infrastructure;
+
+namespace Microsoft.AspNet.PipelineCore
+{
+ public class DefaultCanHasResponseCookies : ICanHasResponseCookies
+ {
+ private readonly IFeatureCollection _features;
+ private FeatureReference _request = FeatureReference.Default;
+ private IResponseCookiesCollection _cookiesCollection;
+
+ public DefaultCanHasResponseCookies(IFeatureCollection features)
+ {
+ _features = features;
+ }
+
+ public IResponseCookiesCollection Cookies
+ {
+ get
+ {
+ var headers = _request.Fetch(_features).Headers;
+ if (_cookiesCollection == null)
+ {
+ _cookiesCollection = new ResponseCookiesCollection(new HeaderDictionary(headers));
+ }
+
+ return _cookiesCollection;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.PipelineCore/DefaultHttpResponse.cs b/src/Microsoft.AspNet.PipelineCore/DefaultHttpResponse.cs
index c1ec42c5d0..4351f7a18d 100644
--- a/src/Microsoft.AspNet.PipelineCore/DefaultHttpResponse.cs
+++ b/src/Microsoft.AspNet.PipelineCore/DefaultHttpResponse.cs
@@ -16,6 +16,7 @@ namespace Microsoft.AspNet.PipelineCore
private readonly DefaultHttpContext _context;
private readonly IFeatureCollection _features;
private FeatureReference _response = FeatureReference.Default;
+ private FeatureReference _canHasCookies = FeatureReference.Default;
public DefaultHttpResponse(DefaultHttpContext context, IFeatureCollection features)
{
@@ -28,6 +29,11 @@ namespace Microsoft.AspNet.PipelineCore
get { return _response.Fetch(_features); }
}
+ private ICanHasResponseCookies CanHasResponseCookies
+ {
+ get { return _canHasCookies.Fetch(_features) ?? _canHasCookies.Update(_features, new DefaultCanHasResponseCookies(_features)); }
+ }
+
public override HttpContext HttpContext { get { return _context; } }
public override int StatusCode
@@ -79,6 +85,10 @@ namespace Microsoft.AspNet.PipelineCore
}
}
+ public override IResponseCookiesCollection Cookies
+ {
+ get { return CanHasResponseCookies.Cookies; }
+ }
public override Task WriteAsync(string data)
{
var bytes = Encoding.UTF8.GetBytes(data);
diff --git a/src/Microsoft.AspNet.PipelineCore/ICanHasResponseCookies.cs b/src/Microsoft.AspNet.PipelineCore/ICanHasResponseCookies.cs
new file mode 100644
index 0000000000..23c73d4d2a
--- /dev/null
+++ b/src/Microsoft.AspNet.PipelineCore/ICanHasResponseCookies.cs
@@ -0,0 +1,10 @@
+using Microsoft.AspNet.Abstractions;
+using Microsoft.AspNet.PipelineCore.Collections;
+
+namespace Microsoft.AspNet.PipelineCore
+{
+ public interface ICanHasResponseCookies
+ {
+ IResponseCookiesCollection Cookies { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.PipelineCore/Infrastructure/Constants.cs b/src/Microsoft.AspNet.PipelineCore/Infrastructure/Constants.cs
index 114ae660e3..cc92a10786 100644
--- a/src/Microsoft.AspNet.PipelineCore/Infrastructure/Constants.cs
+++ b/src/Microsoft.AspNet.PipelineCore/Infrastructure/Constants.cs
@@ -18,6 +18,7 @@ namespace Microsoft.AspNet.Abstractions.Infrastructure
internal const string ETag = "ETag";
internal const string Location = "Location";
internal const string ContentLength = "Content-Length";
+ internal const string Cookie = "Cookie";
internal const string SetCookie = "Set-Cookie";
internal const string Expires = "Expires";
}