1 //------------------------------------------------------------------------------
2 // <copyright file="HttpCookie.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
8 * HttpCookie - collection + name + path
10 * Copyright (c) 1998 Microsoft Corporation
13 namespace System
.Web
{
15 using System
.Collections
;
16 using System
.Collections
.Specialized
;
17 using System
.Globalization
;
18 using System
.Security
.Permissions
;
19 using System
.Web
.Configuration
;
20 using System
.Web
.Management
;
25 /// Provides a type-safe way
26 /// to access multiple HTTP cookies.
29 public sealed class HttpCookie
{
31 private String _path
= "/";
33 private bool _httpOnly
;
34 private String _domain
;
35 private bool _expirationSet
;
36 private DateTime _expires
;
37 private String _stringValue
;
38 private HttpValueCollection _multiValue
;
39 private bool _changed
;
42 internal HttpCookie() {
47 * Constructor - empty cookie with name
52 /// Initializes a new instance of the <see cref='System.Web.HttpCookie'/>
56 public HttpCookie(String name
) {
59 SetDefaultsFromConfig();
64 * Constructor - cookie with name and value
69 /// Initializes a new instance of the <see cref='System.Web.HttpCookie'/>
73 public HttpCookie(String name
, String
value) {
77 SetDefaultsFromConfig();
81 private void SetDefaultsFromConfig() {
82 HttpCookiesSection config
= RuntimeConfig
.GetConfig().HttpCookies
;
83 _secure
= config
.RequireSSL
;
84 _httpOnly
= config
.HttpOnlyCookies
;
86 if (config
.Domain
!= null && config
.Domain
.Length
> 0)
87 _domain
= config
.Domain
;
91 * Whether the cookie contents have changed
93 internal bool Changed
{
94 get { return _changed; }
95 set { _changed = value; }
99 * Whether the cookie has been added
101 internal bool Added
{
102 get { return _added; }
103 set { _added = value; }
106 // DevID 251951 Cookie is getting duplicated by ASP.NET when they are added via a native module
107 // This flag is used to remember that this cookie came from an IIS Set-Header flag,
108 // so we don't duplicate it and send it back to IIS
109 internal bool IsInResponseHeader
{
121 /// or sets the name of cookie.
138 /// Gets or sets the URL prefix to transmit with the
156 /// Indicates whether the cookie should be transmitted only over HTTPS.
160 get { return _secure;}
168 /// Determines whether this cookie is allowed to participate in output caching.
171 /// If a given HttpResponse contains one or more outbound cookies with Shareable = false (the default value),
172 /// output caching will be suppressed for that response. This prevents cookies that contain potentially
173 /// sensitive information, e.g. FormsAuth cookies, from being cached in the response and sent to multiple
174 /// clients. If a developer wants to allow a response containing cookies to be cached, he should configure
175 /// caching as normal for the response, e.g. via the OutputCache directive, MVC's [OutputCache] attribute,
176 /// etc., and he should make sure that all outbound cookies are marked Shareable = true.
178 public bool Shareable
{
180 set; // don't need to set _changed flag since Set-Cookie header isn't affected by value of Shareable
185 /// Indicates whether the cookie should have HttpOnly attribute
188 public bool HttpOnly
{
189 get { return _httpOnly;}
202 /// Restricts domain cookie is to be used with.
205 public String Domain
{
206 get { return _domain;}
219 /// Expiration time for cookie (in minutes).
222 public DateTime Expires
{
224 return(_expirationSet
? _expires
: DateTime
.MinValue
);
229 _expirationSet
= true;
235 * Cookie value as string
242 /// sets an individual cookie value.
245 public String Value
{
247 if (_multiValue
!= null)
248 return _multiValue
.ToString(false);
254 if (_multiValue
!= null) {
255 // reset multivalue collection to contain
256 // single keyless value
258 _multiValue
.Add(null, value);
261 // remember as string
262 _stringValue
= value;
269 * Checks is cookie has sub-keys
274 /// value indicating whether the cookie has sub-keys.</para>
276 public bool HasKeys
{
277 get { return Values.HasKeys();}
280 private bool SupportsHttpOnly(HttpContext context
) {
281 if (context
!= null && context
.Request
!= null) {
282 HttpBrowserCapabilities browser
= context
.Request
.Browser
;
283 return (browser
!= null && (browser
.Type
!= "IE5" || browser
.Platform
!= "MacPPC"));
289 * Cookie values as multivalue collection
293 /// <para>Gets individual key:value pairs within a single cookie object.</para>
295 public NameValueCollection Values
{
297 if (_multiValue
== null) {
298 // create collection on demand
299 _multiValue
= new HttpValueCollection();
301 // convert existing string value into multivalue
302 if (_stringValue
!= null) {
303 if (_stringValue
.IndexOf('&') >= 0 || _stringValue
.IndexOf('=') >= 0)
304 _multiValue
.FillFromString(_stringValue
);
306 _multiValue
.Add(null, _stringValue
);
319 * Default indexed property -- lookup the multivalue collection
324 /// Shortcut for HttpCookie$Values[key]. Required for ASP compatibility.
327 public String
this[String key
]
340 * Construct set-cookie header
342 internal HttpResponseHeader
GetSetCookieHeader(HttpContext context
) {
343 StringBuilder s
= new StringBuilder();
346 if (!String
.IsNullOrEmpty(_name
)) {
352 if (_multiValue
!= null)
353 s
.Append(_multiValue
.ToString(false));
354 else if (_stringValue
!= null)
355 s
.Append(_stringValue
);
358 if (!String
.IsNullOrEmpty(_domain
)) {
359 s
.Append("; domain=");
364 if (_expirationSet
&& _expires
!= DateTime
.MinValue
) {
365 s
.Append("; expires=");
366 s
.Append(HttpUtility
.FormatHttpCookieDateTime(_expires
));
370 if (!String
.IsNullOrEmpty(_path
)) {
377 s
.Append("; secure");
379 // httponly, Note: IE5 on the Mac doesn't support this
380 if (_httpOnly
&& SupportsHttpOnly(context
)) {
381 s
.Append("; HttpOnly");
384 // return as HttpResponseHeader
385 return new HttpResponseHeader(HttpWorkerRequest
.HeaderSetCookie
, s
.ToString());
389 /////////////////////////////////////////////////////////////////////////////
390 /////////////////////////////////////////////////////////////////////////////
391 /////////////////////////////////////////////////////////////////////////////
393 public enum HttpCookieMode
{
395 UseUri
, // cookieless=true
397 UseCookies
, // cookieless=false
399 AutoDetect
, // cookieless=AutoDetect; Probe if device is cookied
401 UseDeviceProfile
// cookieless=UseDeviceProfile; Base decision on caps