Merge branch 'myeisha-xml-fixes'
[mono.git] / mcs / class / System.Web / System.Web / ServerVariablesCollection.cs
1 //
2 // System.Web.ServerVariablesCollection
3 //
4 // Authors:
5 //      Alon Gazit (along@mainsoft.com)
6 //      Miguel de Icaza (miguel@novell.com)
7 //      Gonzalo Paniagua Javier (gonzalo@novell.com)
8 //
9 // (c) 2004 Mainsoft, Inc. (http://www.mainsoft.com)
10 // Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.Text;
33 using System.Collections;
34 using System.Collections.Specialized;
35 using System.Runtime.Serialization;
36 using System.Globalization;
37 using System.Security.Permissions;
38 using System.Security.Principal;
39 using System.Web.Util;
40
41 namespace System.Web
42 {
43         sealed class ServerVariablesCollection : BaseParamsCollection
44         {
45                 bool loaded;
46
47                 string QueryString {
48                         get {
49                                 string qs = _request.QueryStringRaw;
50
51                                 if (String.IsNullOrEmpty (qs))
52                                         return qs;
53
54                                 if (qs [0] == '?')
55                                         return qs.Substring (1);
56
57                                 return qs;
58                         }
59                 }
60
61                 IIdentity UserIdentity {
62                         get {
63                                 HttpContext context = _request != null ? _request.Context : null;
64                                 IPrincipal user = context != null ? context.User : null;
65                                 return user != null ? user.Identity : null;
66                         }
67                 }
68                 
69                 public ServerVariablesCollection(HttpRequest request) : base(request)
70                 {
71                         IsReadOnly = true;
72                 }
73
74                 void AppendKeyValue (StringBuilder sb, string key, string value, bool standard)
75                 {
76                         //
77                         // Standard has HTTP_ prefix, everything is uppercase, has no space
78                         // after colon, - is changed to _
79                         //
80                         // Raw is header, colon, space, values, raw.
81                         //
82                         if (standard){
83                                 sb.Append ("HTTP_");
84                                 sb.Append (key.ToUpper (Helpers.InvariantCulture).Replace ('-', '_'));
85                                 sb.Append (":");
86                         } else {
87                                 sb.Append (key);
88                                 sb.Append (": ");
89                         }
90                         sb.Append (value);
91                         sb.Append ("\r\n");
92                 }
93                                      
94                 string Fill (HttpWorkerRequest wr, bool standard)
95                 {
96                         StringBuilder sb = new StringBuilder ();
97                         
98                         for (int i = 0; i < HttpWorkerRequest.RequestHeaderMaximum; i++){
99                                 string val = wr.GetKnownRequestHeader (i);
100                                 if (String.IsNullOrEmpty (val))
101                                         continue;
102                                 string key = HttpWorkerRequest.GetKnownRequestHeaderName (i);
103                                 AppendKeyValue (sb, key, val, standard);
104                         }
105                         string [][] other = wr.GetUnknownRequestHeaders ();
106                         if (other == null)
107                                 return sb.ToString ();
108
109                         for (int i = other.Length; i > 0; ){
110                                 i--;
111                                 AppendKeyValue (sb, other [i][0], other [i][1], standard);
112                         }
113
114                         return sb.ToString ();
115                 }
116
117                 void AddHeaderVariables (HttpWorkerRequest wr)
118                 {
119                         string hname;
120                         string hvalue;
121
122                         // Add all known headers
123                         for (int i = 0; i < HttpWorkerRequest.RequestHeaderMaximum; i++) {
124                                 hvalue = wr.GetKnownRequestHeader (i);
125                                 if (null != hvalue && hvalue.Length > 0) {
126                                         hname = HttpWorkerRequest.GetKnownRequestHeaderName (i);
127                                         if (null != hname && hname.Length > 0)
128                                                 Add ("HTTP_" + hname.ToUpper (Helpers.InvariantCulture).Replace ('-', '_'), hvalue);
129                                 }
130                         }
131
132                         // Get all other headers
133                         string [][] unknown = wr.GetUnknownRequestHeaders ();
134                         if (null != unknown) {
135                                 for (int i = 0; i < unknown.Length; i++) {
136                                         hname = unknown [i][0];
137                                         if (hname == null)
138                                                 continue;
139                                         hvalue = unknown [i][1];
140                                         Add ("HTTP_" + hname.ToUpper (Helpers.InvariantCulture).Replace ('-', '_'), hvalue);
141                                 }
142                         }
143                 }
144
145                 void loadServerVariablesCollection()
146                 {
147                         HttpWorkerRequest wr = _request.WorkerRequest;
148                         if (loaded || (wr == null))
149                                 return;
150
151                         IsReadOnly = false;
152                 
153                         Add("ALL_HTTP", Fill (wr, true));
154                         Add("ALL_RAW",  Fill (wr, false));
155                             
156                         Add("APPL_MD_PATH", wr.GetServerVariable("APPL_MD_PATH"));
157                         Add("APPL_PHYSICAL_PATH", wr.GetServerVariable("APPL_PHYSICAL_PATH"));
158
159                         IIdentity identity = UserIdentity;
160                         
161                         if (identity != null && identity.IsAuthenticated) {
162                                 Add ("AUTH_TYPE", identity.AuthenticationType);
163                                 Add ("AUTH_USER", identity.Name);
164                         } else {
165                                 Add ("AUTH_TYPE", String.Empty);
166                                 Add ("AUTH_USER", String.Empty);
167                         }
168
169                         Add("AUTH_PASSWORD", wr.GetServerVariable("AUTH_PASSWORD"));
170                         Add ("LOGON_USER", wr.GetServerVariable("LOGON_USER"));
171                         Add ("REMOTE_USER", wr.GetServerVariable("REMOTE_USER"));
172                         Add("CERT_COOKIE", wr.GetServerVariable("CERT_COOKIE"));
173                         Add("CERT_FLAGS", wr.GetServerVariable("CERT_FLAGS"));
174                         Add("CERT_ISSUER", wr.GetServerVariable("CERT_ISSUER"));
175                         Add("CERT_KEYSIZE", wr.GetServerVariable("CERT_KEYSIZE"));
176                         Add("CERT_SECRETKEYSIZE", wr.GetServerVariable("CERT_SECRETKEYSIZE"));
177                         Add("CERT_SERIALNUMBER", wr.GetServerVariable("CERT_SERIALNUMBER"));
178                         Add("CERT_SERVER_ISSUER", wr.GetServerVariable("CERT_SERVER_ISSUER"));
179                         Add("CERT_SERVER_SUBJECT", wr.GetServerVariable("CERT_SERVER_SUBJECT"));
180                         Add("CERT_SUBJECT", wr.GetServerVariable("CERT_SUBJECT"));
181
182                         string sTmp = wr.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength);
183                         if (null != sTmp)
184                                 Add ("CONTENT_LENGTH", sTmp);
185                         Add ("CONTENT_TYPE", _request.ContentType);
186
187                         Add("GATEWAY_INTERFACE", wr.GetServerVariable("GATEWAY_INTERFACE"));
188                         Add("HTTPS", wr.GetServerVariable("HTTPS"));
189                         Add("HTTPS_KEYSIZE", wr.GetServerVariable("HTTPS_KEYSIZE"));
190                         Add("HTTPS_SECRETKEYSIZE", wr.GetServerVariable("HTTPS_SECRETKEYSIZE"));
191                         Add("HTTPS_SERVER_ISSUER", wr.GetServerVariable("HTTPS_SERVER_ISSUER"));
192                         Add("HTTPS_SERVER_SUBJECT", wr.GetServerVariable("HTTPS_SERVER_SUBJECT"));
193                         Add("INSTANCE_ID", wr.GetServerVariable("INSTANCE_ID"));
194                         Add("INSTANCE_META_PATH", wr.GetServerVariable("INSTANCE_META_PATH"));
195                         Add("LOCAL_ADDR", wr.GetLocalAddress());
196                         Add("PATH_INFO", _request.PathInfo);
197                         Add("PATH_TRANSLATED", _request.PhysicalPath);
198                         Add("QUERY_STRING", QueryString);
199                         Add("REMOTE_ADDR", _request.UserHostAddress);
200                         Add("REMOTE_HOST", _request.UserHostName);
201                         Add("REMOTE_PORT", wr.GetRemotePort ().ToString ());
202                         Add("REQUEST_METHOD", _request.HttpMethod);
203                         Add("SCRIPT_NAME", _request.FilePath);
204                         Add("SERVER_NAME", wr.GetServerName());
205                         Add("SERVER_PORT", wr.GetLocalPort().ToString());
206                         if (wr.IsSecure()) 
207                                 Add("SERVER_PORT_SECURE", "1");
208                         else
209                                 Add("SERVER_PORT_SECURE", "0");
210                         Add("SERVER_PROTOCOL", wr.GetHttpVersion());
211                         Add("SERVER_SOFTWARE", wr.GetServerVariable("SERVER_SOFTWARE"));
212                         Add ("URL", _request.FilePath);
213
214                         AddHeaderVariables (wr);
215
216                         IsReadOnly = true;
217                         loaded = true;
218                 }
219
220                 protected override void InsertInfo ()
221                 {
222                         loadServerVariablesCollection ();
223                 }
224
225                 protected override string InternalGet (string name)
226                 {
227                         if ((name == null) || (this._request == null))
228                                 return null;
229                         name = name.ToUpper (Helpers.InvariantCulture);
230                         IIdentity identity;
231                         
232                         switch (name) {
233                                 case "AUTH_TYPE":
234                                         identity = UserIdentity;
235                                         if (identity != null && identity.IsAuthenticated)
236                                                 return identity.AuthenticationType;
237                                         else
238                                                 return string.Empty;
239                                 case "AUTH_USER":
240                                         identity = UserIdentity;
241                                         if (identity != null && identity.IsAuthenticated)
242                                                 return identity.Name;
243                                         else
244                                                 return string.Empty;
245                                 case "QUERY_STRING":
246                                         return QueryString;
247                                 case "PATH_INFO":
248                                         return this._request.PathInfo;
249                                 case "PATH_TRANSLATED":
250                                         return this._request.PhysicalPath;
251                                 case "REQUEST_METHOD":
252                                         return this._request.HttpMethod;
253                                 case "REMOTE_ADDR":
254                                         return this._request.UserHostAddress;
255                                 case "REMOTE_HOST":
256                                         return this._request.UserHostName;
257                                 case "REMOTE_ADDRESS":
258                                         return this._request.UserHostAddress;
259                                 case "SCRIPT_NAME":
260                                         return this._request.FilePath;
261                                 case "LOCAL_ADDR":
262                                         return this._request.WorkerRequest.GetLocalAddress ();
263                                 case "SERVER_PROTOCOL":
264                                         return _request.WorkerRequest.GetHttpVersion ();
265                                 case "CONTENT_TYPE":
266                                         return _request.ContentType;
267                                 case "REMOTE_PORT":
268                                         return _request.WorkerRequest.GetRemotePort ().ToString ();
269                                 case "SERVER_NAME":
270                                         return _request.WorkerRequest.GetServerName ();
271                                 case "SERVER_PORT":
272                                         return _request.WorkerRequest.GetLocalPort ().ToString ();
273                                 case "APPL_PHYSICAL_PATH":
274                                         return _request.WorkerRequest.GetAppPathTranslated ();
275                                 case "URL":
276                                         return _request.FilePath;
277                                 case "SERVER_PORT_SECURE":
278                                         return (_request.WorkerRequest.IsSecure ()) ? "1" : "0";
279                                 case "ALL_HTTP":
280                                         return Fill (_request.WorkerRequest, true);
281                                 case "ALL_RAW":
282                                         return Fill (_request.WorkerRequest, false);
283                                 case "REMOTE_USER":
284                                 case "SERVER_SOFTWARE":
285                                 case "APPL_MD_PATH":
286                                 case "AUTH_PASSWORD":
287                                 case "CERT_COOKIE":
288                                 case "CERT_FLAGS":
289                                 case "CERT_ISSUER":
290                                 case "CERT_KEYSIZE":
291                                 case "CERT_SECRETKEYSIZE":
292                                 case "CERT_SERIALNUMBER":
293                                 case "CERT_SERVER_ISSUER":
294                                 case "CERT_SERVER_SUBJECT":
295                                 case "GATEWAY_INTERFACE":
296                                 case "HTTPS":
297                                 case "HTTPS_KEYSIZE":
298                                 case "HTTPS_SECRETKEYSIZE":
299                                 case "HTTPS_SERVER_ISSUER":
300                                 case "HTTPS_SERVER_SUBJECT":
301                                 case "INSTANCE_ID":
302                                 case "INSTANCE_META_PATH":
303                                 case "LOGON_USER":
304                                 case "HTTP_ACCEPT":
305                                 case "HTTP_REFERER":
306                                 case "HTTP_ACCEPT_LANGUAGE":
307                                 case "HTTP_ACCEPT_ENCODING":
308                                 case "HTTP_CONNECTION":
309                                 case "HTTP_HOST":
310                                 case "HTTP_USER_AGENT":
311                                 case "HTTP_SOAPACTION":
312                                         return _request.WorkerRequest.GetServerVariable (name);
313                                 default:
314                                         return null;
315                         }
316                 }
317         }
318 }