Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Web / HttpCookie.cs
blobc5f127e60d692b460a9dc0ee04a2f8d549f333b7
1 //------------------------------------------------------------------------------
2 // <copyright file="HttpCookie.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
7 /*
8 * HttpCookie - collection + name + path
10 * Copyright (c) 1998 Microsoft Corporation
13 namespace System.Web {
14 using System.Text;
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;
23 /// <devdoc>
24 /// <para>
25 /// Provides a type-safe way
26 /// to access multiple HTTP cookies.
27 /// </para>
28 /// </devdoc>
29 public sealed class HttpCookie {
30 private String _name;
31 private String _path = "/";
32 private bool _secure;
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;
40 private bool _added;
42 internal HttpCookie() {
43 _changed = true;
47 * Constructor - empty cookie with name
50 /// <devdoc>
51 /// <para>
52 /// Initializes a new instance of the <see cref='System.Web.HttpCookie'/>
53 /// class.
54 /// </para>
55 /// </devdoc>
56 public HttpCookie(String name) {
57 _name = name;
59 SetDefaultsFromConfig();
60 _changed = true;
64 * Constructor - cookie with name and value
67 /// <devdoc>
68 /// <para>
69 /// Initializes a new instance of the <see cref='System.Web.HttpCookie'/>
70 /// class.
71 /// </para>
72 /// </devdoc>
73 public HttpCookie(String name, String value) {
74 _name = name;
75 _stringValue = value;
77 SetDefaultsFromConfig();
78 _changed = true;
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 {
110 get;
111 set;
115 * Cookie name
118 /// <devdoc>
119 /// <para>
120 /// Gets
121 /// or sets the name of cookie.
122 /// </para>
123 /// </devdoc>
124 public String Name {
125 get { return _name;}
126 set {
127 _name = value;
128 _changed = true;
133 * Cookie path
136 /// <devdoc>
137 /// <para>
138 /// Gets or sets the URL prefix to transmit with the
139 /// current cookie.
140 /// </para>
141 /// </devdoc>
142 public String Path {
143 get { return _path;}
144 set {
145 _path = value;
146 _changed = true;
151 * 'Secure' flag
154 /// <devdoc>
155 /// <para>
156 /// Indicates whether the cookie should be transmitted only over HTTPS.
157 /// </para>
158 /// </devdoc>
159 public bool Secure {
160 get { return _secure;}
161 set {
162 _secure = value;
163 _changed = true;
167 /// <summary>
168 /// Determines whether this cookie is allowed to participate in output caching.
169 /// </summary>
170 /// <remarks>
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.
177 /// </remarks>
178 public bool Shareable {
179 get;
180 set; // don't need to set _changed flag since Set-Cookie header isn't affected by value of Shareable
183 /// <devdoc>
184 /// <para>
185 /// Indicates whether the cookie should have HttpOnly attribute
186 /// </para>
187 /// </devdoc>
188 public bool HttpOnly {
189 get { return _httpOnly;}
190 set {
191 _httpOnly = value;
192 _changed = true;
197 * Cookie domain
200 /// <devdoc>
201 /// <para>
202 /// Restricts domain cookie is to be used with.
203 /// </para>
204 /// </devdoc>
205 public String Domain {
206 get { return _domain;}
207 set {
208 _domain = value;
209 _changed = true;
214 * Cookie expiration
217 /// <devdoc>
218 /// <para>
219 /// Expiration time for cookie (in minutes).
220 /// </para>
221 /// </devdoc>
222 public DateTime Expires {
223 get {
224 return(_expirationSet ? _expires : DateTime.MinValue);
227 set {
228 _expires = value;
229 _expirationSet = true;
230 _changed = true;
235 * Cookie value as string
238 /// <devdoc>
239 /// <para>
240 /// Gets
241 /// or
242 /// sets an individual cookie value.
243 /// </para>
244 /// </devdoc>
245 public String Value {
246 get {
247 if (_multiValue != null)
248 return _multiValue.ToString(false);
249 else
250 return _stringValue;
253 set {
254 if (_multiValue != null) {
255 // reset multivalue collection to contain
256 // single keyless value
257 _multiValue.Reset();
258 _multiValue.Add(null, value);
260 else {
261 // remember as string
262 _stringValue = value;
264 _changed = true;
269 * Checks is cookie has sub-keys
272 /// <devdoc>
273 /// <para>Gets a
274 /// value indicating whether the cookie has sub-keys.</para>
275 /// </devdoc>
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"));
285 return false;
289 * Cookie values as multivalue collection
292 /// <devdoc>
293 /// <para>Gets individual key:value pairs within a single cookie object.</para>
294 /// </devdoc>
295 public NameValueCollection Values {
296 get {
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);
305 else
306 _multiValue.Add(null, _stringValue);
308 _stringValue = null;
312 _changed = true;
314 return _multiValue;
319 * Default indexed property -- lookup the multivalue collection
322 /// <devdoc>
323 /// <para>
324 /// Shortcut for HttpCookie$Values[key]. Required for ASP compatibility.
325 /// </para>
326 /// </devdoc>
327 public String this[String key]
329 get {
330 return Values[key];
333 set {
334 Values[key] = value;
335 _changed = true;
340 * Construct set-cookie header
342 internal HttpResponseHeader GetSetCookieHeader(HttpContext context) {
343 StringBuilder s = new StringBuilder();
345 // cookiename=
346 if (!String.IsNullOrEmpty(_name)) {
347 s.Append(_name);
348 s.Append('=');
351 // key=value&...
352 if (_multiValue != null)
353 s.Append(_multiValue.ToString(false));
354 else if (_stringValue != null)
355 s.Append(_stringValue);
357 // domain
358 if (!String.IsNullOrEmpty(_domain)) {
359 s.Append("; domain=");
360 s.Append(_domain);
363 // expiration
364 if (_expirationSet && _expires != DateTime.MinValue) {
365 s.Append("; expires=");
366 s.Append(HttpUtility.FormatHttpCookieDateTime(_expires));
369 // path
370 if (!String.IsNullOrEmpty(_path)) {
371 s.Append("; path=");
372 s.Append(_path);
375 // secure
376 if (_secure)
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