2 // System.Web.HttpRequest.cs
6 // Miguel de Icaza (miguel@novell.com)
7 // Gonzalo Paniagua Javier (gonzalo@novell.com)
11 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System.Web.Util;
36 using System.Collections.Specialized;
37 using System.Security.Permissions;
40 namespace System.Web {
43 // Methods exposed through HttpContext.Server property
46 // CAS - no InheritanceDemand here as the class is sealed
47 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
48 public sealed class HttpServerUtility {
51 internal HttpServerUtility (HttpContext context)
53 this.context = context;
56 public void ClearError ()
58 context.ClearError ();
61 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
62 public object CreateObject (string progID)
64 throw new HttpException (500, "COM is not supported");
67 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
68 public object CreateObject (Type type)
70 throw new HttpException (500, "COM is not supported");
73 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
74 public object CreateObjectFromClsid (string clsid)
76 throw new HttpException (500, "COM is not supported");
79 public void Execute (string path)
81 Execute (path, null, true);
84 public void Execute (string path, TextWriter writer)
86 Execute (path, writer, true);
90 public void Execute (string path, bool preserveForm)
92 Execute (path, null, preserveForm);
101 void Execute (string path, TextWriter writer, bool preserveForm)
104 throw new ArgumentNullException ("path");
106 if (path.IndexOf (':') != -1)
107 throw new ArgumentException ("Invalid path.");
109 HttpRequest request = context.Request;
110 string oldQuery = request.QueryStringRaw;
111 int qmark = path.IndexOf ('?');
113 request.QueryStringRaw = path.Substring (qmark + 1);
114 path = path.Substring (0, qmark);
115 } else if (!preserveForm) {
116 request.QueryStringRaw = "";
119 HttpResponse response = context.Response;
120 WebROCollection oldForm = null;
122 oldForm = request.Form as WebROCollection;
123 request.SetForm (new WebROCollection ());
126 TextWriter output = writer;
128 output = response.Output;
130 string oldFilePath = request.FilePath;
131 request.SetCurrentExePath (UrlUtils.Combine (request.BaseVirtualDir, path));
132 IHttpHandler handler = context.ApplicationInstance.GetHandler (context);
133 TextWriter previous = null;
136 context.PushHandler (handler);
138 previous = response.SetTextWriter (output);
139 if (!(handler is IHttpAsyncHandler)) {
140 handler.ProcessRequest (context);
142 IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler) handler;
143 IAsyncResult ar = asyncHandler.BeginProcessRequest (context, null, null);
144 ar.AsyncWaitHandle.WaitOne ();
145 asyncHandler.EndProcessRequest (ar);
148 request.SetCurrentExePath (oldFilePath);
149 if (oldQuery != null && oldQuery != "" && oldQuery != request.QueryStringRaw) {
150 oldQuery = oldQuery.Substring (1); // Ignore initial '?'
151 request.QueryStringRaw = oldQuery; // which is added here.
153 response.SetTextWriter (previous);
155 request.SetForm (oldForm);
157 context.PopHandler ();
162 public Exception GetLastError ()
165 return HttpContext.Current.Error;
166 return context.Error;
169 public string HtmlDecode (string s)
171 return HttpUtility.HtmlDecode (s);
174 public void HtmlDecode (string s, TextWriter output)
176 HttpUtility.HtmlDecode (s, output);
179 public string HtmlEncode (string s)
181 return HttpUtility.HtmlEncode (s);
184 public void HtmlEncode (string s, TextWriter output)
186 HttpUtility.HtmlEncode (s, output);
189 public string MapPath (string path)
191 return context.Request.MapPath (path);
194 public void Transfer (string path)
196 // If it's a page and a postback, don't pass form data
198 bool preserveForm = true;
199 if (context.Handler is Page) {
200 Page page = (Page) context.Handler;
201 preserveForm = !page.IsPostBack;
204 Transfer (path, preserveForm);
207 public void Transfer (string path, bool preserveForm)
209 Execute (path, null, preserveForm);
210 context.Response.End ();
213 [MonoTODO ("Not implemented")]
214 public void Transfer (IHttpHandler handler, bool preserveForm)
217 throw new ArgumentNullException ("handler");
219 // TODO: see the MS doc and search for "enableViewStateMac": this method is not
220 // allowed for pages when preserveForm is true and the page IsCallback property
223 Execute (handler, null, preserveForm);
224 context.Response.End ();
227 public void Execute (IHttpHandler handler, TextWriter writer, bool preserveForm)
230 throw new ArgumentNullException ("handler");
232 HttpRequest request = context.Request;
233 string oldQuery = request.QueryStringRaw;
235 request.QueryStringRaw = "";
238 HttpResponse response = context.Response;
239 WebROCollection oldForm = null;
241 oldForm = request.Form as WebROCollection;
242 request.SetForm (new WebROCollection ());
245 TextWriter output = writer;
247 output = response.Output;
249 TextWriter previous = null;
251 previous = response.SetTextWriter (output);
252 if (!(handler is IHttpAsyncHandler)) {
253 handler.ProcessRequest (context);
255 IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler) handler;
256 IAsyncResult ar = asyncHandler.BeginProcessRequest (context, null, null);
257 ar.AsyncWaitHandle.WaitOne ();
258 asyncHandler.EndProcessRequest (ar);
261 if (oldQuery != null && oldQuery != "" && oldQuery != request.QueryStringRaw) {
262 oldQuery = oldQuery.Substring (1); // Ignore initial '?'
263 request.QueryStringRaw = oldQuery; // which is added here.
265 response.SetTextWriter (previous);
267 request.SetForm (oldForm);
271 public static byte[] UrlTokenDecode (string input)
274 throw new ArgumentNullException ("input");
275 if (input.Length < 1)
277 byte[] bytes = Encoding.ASCII.GetBytes (input);
278 int inputLength = input.Length - 1;
279 int equalsCount = (int)(((char)bytes[inputLength]) - 0x30);
280 char[] ret = new char[inputLength + equalsCount];
282 for (; i < inputLength; i++) {
283 switch ((char)bytes[i]) {
293 ret[i] = (char)bytes[i];
297 while (equalsCount > 0) {
302 return Convert.FromBase64CharArray (ret, 0, ret.Length);
305 public static string UrlTokenEncode (byte[] input)
308 throw new ArgumentNullException ("input");
309 if (input.Length < 1)
311 string base64 = Convert.ToBase64String (input);
313 if (base64 == null || (retlen = base64.Length) == 0)
316 // MS.NET implementation seems to process the base64
317 // string before returning. It replaces the chars:
322 // Then removes trailing ==, which may appear in the
323 // base64 string, and replaces them with a single digit
324 // that's the count of removed '=' characters (0 if none
326 int equalsCount = 0x30;
327 while (retlen > 0 && base64[retlen - 1] == '=') {
331 char[] chars = new char[retlen + 1];
332 chars[retlen] = (char)equalsCount;
333 for (int i = 0; i < retlen; i++) {
344 chars[i] = base64[i];
348 return new string (chars);
352 public string UrlDecode (string s)
354 return HttpUtility.UrlDecode (s);
357 public void UrlDecode (string s, TextWriter output)
360 output.Write (HttpUtility.UrlDecode (s));
363 public string UrlEncode (string s)
365 return HttpUtility.UrlEncode (s);
368 public void UrlEncode (string s, TextWriter output)
371 output.Write (HttpUtility.UrlEncode (s));
374 public string UrlPathEncode (string s)
379 int idx = s.IndexOf ("?");
382 s2 = s.Substring (0, idx-1);
383 s2 = HttpUtility.UrlEncode (s2) + s.Substring (idx);
385 s2 = HttpUtility.UrlEncode (s);
391 public string MachineName {
392 [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
393 // Medium doesn't look heavy enough to replace this... reported as
394 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
395 [EnvironmentPermission (SecurityAction.Assert, Read = "COMPUTERNAME")]
396 get { return Environment.MachineName; }
399 public int ScriptTimeout {
400 get { return (int) context.ConfigTimeout.TotalSeconds; }
401 [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
402 set { context.ConfigTimeout = new TimeSpan (0, 0, value); }