Improve request and response cookie handling.
This commit is contained in:
parent
ca2ef860f5
commit
ae9545a124
|
|
@ -20,3 +20,5 @@ nuget.exe
|
|||
*.userprefs
|
||||
*DS_Store
|
||||
*.ncrunchsolution
|
||||
*.*sdf
|
||||
*.ipch
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
namespace Microsoft.AspNet.Abstractions
|
||||
{
|
||||
/// <summary>
|
||||
/// A wrapper for the response Set-Cookie header
|
||||
/// </summary>
|
||||
public interface IResponseCookiesCollection
|
||||
{
|
||||
/// <summary>
|
||||
/// Add a new cookie and value
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
void Append(string key, string value);
|
||||
|
||||
/// <summary>
|
||||
/// Add a new cookie
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="options"></param>
|
||||
void Append(string key, string value, CookieOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Sets an expired cookie
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
void Delete(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Sets an expired cookie
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="options"></param>
|
||||
void Delete(string key, CookieOptions options);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.AspNet.PipelineCore.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// A wrapper for the request Cookie header
|
||||
/// </summary>
|
||||
public class RequestCookieCollection : IEnumerable<KeyValuePair<string, string>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new wrapper
|
||||
/// </summary>
|
||||
/// <param name="store"></param>
|
||||
public RequestCookieCollection(IDictionary<string, string> store)
|
||||
{
|
||||
if (store == null)
|
||||
{
|
||||
throw new ArgumentNullException("store");
|
||||
}
|
||||
|
||||
Store = store;
|
||||
}
|
||||
|
||||
private IDictionary<string, string> Store { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns null rather than throwing KeyNotFoundException
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public string this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
string value;
|
||||
Store.TryGetValue(key, out value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
|
||||
{
|
||||
return Store.GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// A wrapper for the response Set-Cookie header
|
||||
/// </summary>
|
||||
public class ResponseCookieCollection
|
||||
public class ResponseCookiesCollection : IResponseCookiesCollection
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new wrapper
|
||||
/// </summary>
|
||||
/// <param name="headers"></param>
|
||||
public ResponseCookieCollection(IHeaderDictionary headers)
|
||||
public ResponseCookiesCollection(IHeaderDictionary headers)
|
||||
{
|
||||
if (headers == null)
|
||||
{
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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<IHttpResponseInformation> _request = FeatureReference<IHttpResponseInformation>.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ namespace Microsoft.AspNet.PipelineCore
|
|||
private readonly DefaultHttpContext _context;
|
||||
private readonly IFeatureCollection _features;
|
||||
private FeatureReference<IHttpResponseInformation> _response = FeatureReference<IHttpResponseInformation>.Default;
|
||||
private FeatureReference<ICanHasResponseCookies> _canHasCookies = FeatureReference<ICanHasResponseCookies>.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);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
using Microsoft.AspNet.Abstractions;
|
||||
using Microsoft.AspNet.PipelineCore.Collections;
|
||||
|
||||
namespace Microsoft.AspNet.PipelineCore
|
||||
{
|
||||
public interface ICanHasResponseCookies
|
||||
{
|
||||
IResponseCookiesCollection Cookies { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue