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 
ServerVariablesCollection(HttpRequest request)69 		public ServerVariablesCollection(HttpRequest request) : base(request)
70 		{
71 			IsReadOnly = true;
72 		}
73 
AppendKeyValue(StringBuilder sb, string key, string value, bool standard)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 
Fill(HttpWorkerRequest wr, bool standard)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 
AddHeaderVariables(HttpWorkerRequest wr)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 
loadServerVariablesCollection()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 
InsertInfo()220 		protected override void InsertInfo ()
221 		{
222 			loadServerVariablesCollection ();
223 		}
224 
InternalGet(string name)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 }
319