2005-10-03 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web / HttpServerUtility.cs
1 //
2 // System.Web.HttpRequest.cs 
3 //
4 // 
5 // Author:
6 //      Miguel de Icaza (miguel@novell.com)
7 //      Gonzalo Paniagua Javier (gonzalo@novell.com)
8 //
9
10 //
11 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
12 //
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:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
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.
31 //
32
33 using System.IO;
34 using System.Web.UI;
35 using System.Web.Util;
36 using System.Collections.Specialized;
37 using System.Security.Permissions;
38
39 namespace System.Web {
40
41         //
42         // Methods exposed through HttpContext.Server property
43         //
44         
45         // CAS - no InheritanceDemand here as the class is sealed
46         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
47         public sealed class HttpServerUtility {
48                 HttpContext context;
49                 
50                 internal HttpServerUtility (HttpContext context)
51                 {
52                         this.context = context;
53                 }
54
55                 public void ClearError ()
56                 {
57                         context.ClearError ();
58                 }
59
60                 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
61                 public object CreateObject (string progID)
62                 {
63                         throw new HttpException (500, "COM is not supported");
64                 }
65
66                 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
67                 public object CreateObject (Type type)
68                 {
69                         throw new HttpException (500, "COM is not supported");
70                 }
71
72                 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
73                 public object CreateObjectFromClsid (string clsid)
74                 {
75                         throw new HttpException (500, "COM is not supported");
76                 }
77
78                 public void Execute (string path)
79                 {
80                         Execute (path, null);
81                 }
82
83                 public void Execute (string path, TextWriter writer)
84                 {
85                         Execute (path, writer, false);
86                 }
87
88 #if NET_2_0
89                 public
90 #else
91                 internal
92 #endif
93                 void Execute (string path, TextWriter writer, bool preserveQuery)
94                 {
95                         if (path == null)
96                                 throw new ArgumentNullException ("path");
97
98                         if (path.IndexOf (':') != -1)
99                                 throw new ArgumentException ("Invalid path.");
100
101                         int qmark = path.IndexOf ('?');
102                         string query;
103                         if (qmark != -1) {
104                                 query = path.Substring (qmark + 1);
105                                 path = path.Substring (0, qmark);
106                         } else {
107                                 query = "";
108                         }
109
110                         HttpRequest request = context.Request;
111                         HttpResponse response = context.Response;
112
113                         string oldQuery = request.QueryStringRaw;
114                         request.QueryStringRaw = query;
115
116                         WebROCollection oldForm = null;
117                         if (!preserveQuery) {
118                                 oldForm = request.Form as WebROCollection;
119                                 request.SetForm (new WebROCollection ());
120                         }
121
122                         TextWriter output = writer;
123                         if (output == null)
124                                 output = response.Output;
125
126                         string oldFilePath = request.FilePath;
127                         request.SetCurrentExePath (UrlUtils.Combine (request.BaseVirtualDir, path));
128                         IHttpHandler handler = context.ApplicationInstance.GetHandler (context);
129                         TextWriter previous = null;
130                         try {
131                                 previous = response.SetTextWriter (output);
132                                 if (!(handler is IHttpAsyncHandler)) {
133                                         handler.ProcessRequest (context);
134                                 } else {
135                                         IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler) handler;
136                                         IAsyncResult ar = asyncHandler.BeginProcessRequest (context, null, null);
137                                         ar.AsyncWaitHandle.WaitOne ();
138                                         asyncHandler.EndProcessRequest (ar);
139                                 }
140                         } finally {
141                                 request.SetCurrentExePath (oldFilePath);
142                                 request.QueryStringRaw = oldQuery;
143                                 response.SetTextWriter (previous);
144                                 if (!preserveQuery)
145                                         request.SetForm (oldForm);
146                         }
147                 }
148
149                 public Exception GetLastError ()
150                 {
151                         return context.Error;
152                 }
153
154                 public string HtmlDecode (string s)
155                 {
156                         return HttpUtility.HtmlDecode (s);
157                 }
158
159                 public void HtmlDecode (string s, TextWriter output)
160                 {
161                         HttpUtility.HtmlDecode (s, output);
162                 }
163
164                 public string HtmlEncode (string s)
165                 {
166                         return HttpUtility.HtmlEncode (s);
167                 }
168
169                 public void HtmlEncode (string s, TextWriter output)
170                 {
171                         HttpUtility.HtmlEncode (s, output);
172                 }
173
174                 public string MapPath (string path)
175                 {
176                         return context.Request.MapPath (path);
177                 }
178
179                 public void Transfer (string path)
180                 {
181                         // If it's a page and a postback, don't pass form data
182                         // See bug #65613.
183                         bool preserveForm = true;
184                         if (context.Handler is Page) {
185                                 Page page = (Page) context.Handler;
186                                 preserveForm = !page.IsPostBack;
187                         }
188
189                         Transfer (path, preserveForm);
190                 }
191
192                 public void Transfer (string path, bool preserveForm)
193                 {
194                         Execute (path, null, preserveForm);
195                         context.Response.End ();
196                 }
197 #if NET_2_0
198                 [MonoTODO]
199                 public void Transfer (IHttpHandler handler, bool preserveForm)
200                 {
201                         throw new NotImplementedException ();
202                 }
203 #endif
204                 public string UrlDecode (string s)
205                 {
206                         return HttpUtility.UrlDecode (s);
207                 }
208
209                 public void UrlDecode (string s, TextWriter output)
210                 {
211                         if (s != null)
212                                 output.Write (HttpUtility.UrlDecode (s));
213                 }
214
215                 public string UrlEncode (string s)
216                 {
217                         return HttpUtility.UrlEncode (s);
218                 }
219
220                 public void UrlEncode (string s, TextWriter output)
221                 {
222                         if (s != null)
223                                 output.Write (HttpUtility.UrlEncode (s));
224                 }
225
226                 public string UrlPathEncode (string s)
227                 {
228                         if (s == null)
229                                 return null;
230
231                         int idx = s.IndexOf ("?");
232                         string s2 = null;
233                         if (idx != -1) {
234                                 s2 = s.Substring (0, idx-1);
235                                 s2 = HttpUtility.UrlEncode (s2) + s.Substring (idx);
236                         } else {
237                                 s2 = HttpUtility.UrlEncode (s);
238                         }
239
240                         return s2;
241                 }
242
243                 public string MachineName {
244                         [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
245                         // Medium doesn't look heavy enough to replace this... reported as
246                         [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
247                         [EnvironmentPermission (SecurityAction.Assert, Read = "COMPUTERNAME")]
248                         get { return Environment.MachineName; }
249                 }
250
251                 public int ScriptTimeout {
252                         get { return (int) context.ConfigTimeout.TotalSeconds; }
253                         [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
254                         set { context.ConfigTimeout = new TimeSpan (0, 0, value); }
255                 }
256         }
257 }