2004-08-22 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web / HttpServerUtility.cs
1
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
10 // 
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 // 
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 /**
23  * Namespace: System.Web
24  * Class:     HttpServerUtility
25  *
26  * Authosr:
27  *      Wictor Wilén (wictor@ibizkit.se)
28  *      Patrik Torstensson (patrik.torstensson@labs2.com)
29  *      Gonzalo Paniagua Javier (gonzalo@ximian.com)
30  *
31  * (c) Wictor Wilén (2002)
32  * (c) 2002 Patrik Torstensson
33  * (c) 2003 Ximian, Inc. (http://www.ximian.com)
34  *
35  * (This log is no longer maintained)
36  * ---------------------------------------
37  * 2002-03-27  Wictor      Started implementation
38  * 2002-04-09  Patrik      Added HttpContext constructor
39  * 2002-04-10  Patrik      Moved encoding to HttpUtility and
40  *                         fixed all functions that used
41  *                         HttpContext
42  * 
43  */
44 using System;
45 using System.Collections.Specialized;
46 using System.IO;
47 using System.Text;
48 using System.Web.Hosting;
49 using System.Web.Util;
50
51 namespace System.Web
52 {
53         public sealed class HttpServerUtility
54         {
55                 private static string _name;
56
57                 private HttpContext _Context;
58                 private HttpApplication _Application;
59
60                 internal HttpServerUtility (HttpContext Context)
61                 {
62                         _Context = Context;
63                 }
64
65                 internal HttpServerUtility (HttpApplication app)
66                 {
67                         _Application = app;
68                 }
69
70                 // Properties
71
72
73                 /// <summary>
74                 /// Gets the server's computer name.
75                 /// </summary>
76                 public string MachineName {
77                         get {
78                                 if(_name == null)
79                                         _name = Environment.MachineName;
80
81                                 return _name;
82                         }
83                 }
84
85                 public int ScriptTimeout {
86                         get {
87                                 return (int) _Context.ConfigTimeout.TotalSeconds;
88                         } 
89                         set {
90                                 if (value <= 0)
91                                         throw new ArgumentOutOfRangeException ("value");
92
93                                 _Context.ConfigTimeout = new TimeSpan (0, 0, value);
94                         }
95                 }
96
97                 // Methods
98
99                 /// <summary>
100                 /// Clears the previous exception.
101                 /// </summary>
102                 public void ClearError ()
103                 {
104                         if (null != _Context) {
105                                 _Context.ClearError ();
106                                 return;
107                         }
108
109                         if (null != _Application) {
110                                 _Application.ClearError ();
111                         }
112                 }
113
114
115                 /// <summary>
116                 /// Creates a server instance of a COM object identified by the object's Programmatic Identifier (ProgID).
117                 /// </summary>
118                 /// <param name="progID">The class or type of object to be instantiated. </param>
119                 /// <returns>The new object.</returns>
120                 public object CreateObject (string progID)
121                 {
122                         return CreateObject (Type.GetTypeFromProgID (progID));
123                 }
124
125
126                 /// <summary>
127                 /// Creates a server instance of a COM object identified by the object's type.
128                 /// </summary>
129                 /// <param name="type">A Type representing the object to create. </param>
130                 /// <returns>The new object.</returns>
131                 public object CreateObject (Type type)
132                 {
133                         return Activator.CreateInstance (type);
134                 }
135
136
137                 /// <summary>
138                 /// Creates a server instance of a COM object identified by the object's class identifier (CLSID).
139                 /// </summary>
140                 /// <param name="clsid">The class identifier of the object to be instantiated. </param>
141                 /// <returns>The new object.</returns>
142                 public object CreateObjectFromClsid (string clsid)
143                 {
144                         Guid guid = new Guid (clsid);
145                         return CreateObject (Type.GetTypeFromCLSID (guid));
146                 }
147
148
149                 /// <summary>
150                 /// Executes a request to another page using the specified URL path to the page.
151                 /// </summary>
152                 /// <param name="path">The URL path of the new request. </param>
153                 public void Execute (string path)
154                 {
155                         Execute (path, null);
156                 }
157
158
159                 /// <summary>
160                 /// Executes a request to another page using the specified URL path to the page.
161                 /// A TextWriter captures output from the page.
162                 /// </summary>
163                 /// <param name="path">The URL path of the new request. </param>
164                 /// <param name="writer">The TextWriter to capture the output. </param>
165                 public void Execute (string path, TextWriter writer)
166                 {
167                         Execute (path, writer, false);
168                 }
169
170 #if NET_2_0
171                 public
172 #else
173                 internal
174 #endif
175                 void Execute (string path, TextWriter writer, bool preserveQuery)
176                 {
177                         if (path == null)
178                                 throw new ArgumentNullException ("path");
179
180                         if (_Context == null)
181                                 throw new HttpException ("No context available.");
182
183                         if (path.IndexOf (':') != -1)
184                                 throw new ArgumentException ("Invalid path.");
185
186                         int qmark = path.IndexOf ('?');
187                         string query;
188                         if (qmark != -1) {
189                                 query = path.Substring (qmark + 1);
190                                 path = path.Substring (0, qmark);
191                         } else {
192                                 query = "";
193                         }
194                         
195                         string filePath = _Context.Request.MapPath (path);
196                         HttpResponse response = _Context.Response;
197                         TextWriter output = writer;
198                         if (output == null)
199                                 output = response.Output;
200
201                         HttpRequest request = _Context.Request;
202                         string oldFilePath = request.FilePath;
203                         request.SetFilePath (UrlUtils.Combine (_Context.Request.BaseVirtualDir, path));
204                         string oldQuery = request.QueryStringRaw;
205                         
206                         if (!preserveQuery)     request.QueryStringRaw = query;
207                         IHttpHandler handler = _Context.ApplicationInstance.CreateHttpHandler (_Context,
208                                                                                                request.RequestType,
209                                                                                                path,
210                                                                                                filePath);
211                         TextWriter previous = null;
212                         try {
213                                 previous = response.SetTextWriter (output);
214                                 if (!(handler is IHttpAsyncHandler)) {
215                                         handler.ProcessRequest (_Context);
216                                 } else {
217                                         IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler) handler;
218                                         IAsyncResult ar = asyncHandler.BeginProcessRequest (_Context, null, null);
219                                         ar.AsyncWaitHandle.WaitOne ();
220                                         asyncHandler.EndProcessRequest (ar);
221                                 }
222                         } finally {
223                                 request.SetFilePath (oldFilePath);
224                                 request.QueryStringRaw = oldQuery;
225                                 response.SetTextWriter (previous);
226                         }
227
228                 }
229
230                 /// <summary>
231                 /// Returns the previous exception.
232                 /// </summary>
233                 /// <returns>The previous exception that was thrown.</returns>
234                 public Exception GetLastError ()
235                 {
236                         if (_Context == null)
237                                 return null;
238
239                         return _Context.Error;
240                 }
241
242
243
244                 /// <summary>
245                 /// Decodes an HTML-encoded string and returns the decoded string.
246                 /// </summary>
247                 /// <param name="s">The HTML string to decode. </param>
248                 /// <returns>The decoded text.</returns>
249                 public string HtmlDecode (string s)
250                 {
251                         return HttpUtility.HtmlDecode (s);
252                 }
253
254
255                 /// <summary>
256                 /// Decodes an HTML-encoded string and sends the resulting output to a TextWriter output stream.
257                 /// </summary>
258                 /// <param name="s">The HTML string to decode</param>
259                 /// <param name="output">The TextWriter output stream containing the decoded string. </param>
260                 public void HtmlDecode (string s, TextWriter output)
261                 {
262                         output.Write (HttpUtility.HtmlDecode (s));
263                 }
264
265                 /// <summary>
266                 /// HTML-encodes a string and returns the encoded string.
267                 /// </summary>
268                 /// <param name="s">The text string to encode. </param>
269                 /// <returns>The HTML-encoded text.</returns>
270                 public string HtmlEncode (string s)
271                 {
272                         return HttpUtility.HtmlEncode (s);
273                 }
274
275                 /// <summary>
276                 /// HTML-encodes a string and sends the resulting output to a TextWriter output stream.
277                 /// </summary>
278                 /// <param name="s">The string to encode. </param>
279                 /// <param name="output">The TextWriter output stream containing the encoded string. </param>
280                 public void HtmlEncode (string s, TextWriter output)
281                 {
282                         output.Write (HtmlEncode (s));
283                 }
284
285
286                 /// <summary>
287                 /// Returns the physical file path that corresponds to the specified virtual path on the Web server.
288                 /// </summary>
289                 /// <param name="path">The virtual path on the Web server. </param>
290                 /// <returns>The physical file path that corresponds to path.</returns>
291                 public string MapPath (string path)
292                 {
293                         if (null == _Context)
294                                 throw new HttpException ("MapPath is not available");
295
296                         return _Context.Request.MapPath (path);
297                 }
298
299                 /// <summary>
300                 /// Terminates execution of the current page and begins execution of a new page using the specified
301                 /// URL path to the page.
302                 /// </summary>
303                 /// <param name="path">The URL path of the new page on the server to execute. </param>
304                 public void Transfer (string path)
305                 {
306                         Transfer (path, true);
307                 }
308
309                 /// <summary>
310                 /// Terminates execution of the current page and begins execution of a new page using the specified
311                 /// URL path to the page. Specifies whether to clear the QueryString and Form collections.
312                 /// </summary>
313                 /// <param name="path">The URL path of the new page on the server to execute. </param>
314                 /// <param name="preserveForm">If true, the QueryString and Form collections are preserved. If false,
315                 /// they are cleared. The default is false. </param>
316                 public void Transfer (string path, bool preserveForm)
317                 {
318                         HttpValueCollection oldForm = null;
319                         if (!preserveForm) {
320                                 oldForm = _Context.Request.Form as HttpValueCollection;
321                                 _Context.Request.SetForm (new HttpValueCollection ());
322                         }
323
324                         Execute (path, null, preserveForm);
325                         if (!preserveForm)
326                                 _Context.Request.SetForm (oldForm);
327
328                         _Context.Response.End ();
329                 }
330
331                 /// <summary>
332                 /// URL-decodes a string and returns the decoded string.
333                 /// </summary>
334                 /// <param name="s">The text string to decode. </param>
335                 /// <returns>The decoded text.</returns>
336                 /// <remarks>
337                 /// Post/html encoding @ ftp://ftp.isi.edu/in-notes/rfc1866.txt
338                 /// Uncomment the line marked with RFC1738 to get pure RFC1738
339                 /// and it will also consider the RFC1866 (ftp://ftp.isi.edu/in-notes/rfc1866.txt)
340                 /// `application/x-www-form-urlencoded' format
341                 /// </remarks>
342                 public string UrlDecode (string s)
343                 {
344                         return HttpUtility.UrlDecode (s);
345                 }
346
347                 /// <summary>
348                 /// Decodes an HTML string received in a URL and sends the resulting output to a TextWriter output stream.
349                 /// </summary>
350                 /// <param name="s"></param>
351                 /// <param name="output"></param>
352                 public void UrlDecode (string s, TextWriter output)
353                 {
354                         if (s != null)
355                                 output.Write (UrlDecode (s));
356                 }
357
358                 /// <summary>
359                 /// URL-encodes a string and returns the encoded string.
360                 /// </summary>
361                 /// <param name="s">The text to URL-encode. </param>
362                 /// <returns>The URL encoded text.</returns>
363                 public string UrlEncode (string s)
364                 {
365                         return HttpUtility.UrlEncode (s);
366                 }
367
368                 /// <summary>
369                 /// URL encodes a string and sends the resulting output to a TextWriter output stream.
370                 /// </summary>
371                 /// <param name="s">The text string to encode. </param>
372                 /// <param name="output">The TextWriter output stream containing the encoded string. </param>
373                 public void UrlEncode (string s, TextWriter output)
374                 {
375                         if (s != null)
376                                 output.Write (UrlEncode (s));
377                 }
378
379                 /// <summary>
380                 /// URL-encodes the path portion of a URL string and returns the encoded string.
381                 /// </summary>
382                 /// <param name="s">The text to URL-encode.</param>
383                 /// <returns>The URL encoded text.</returns>
384                 /// <remarks>Does not do any browser specific adjustments, just encode everything</remarks>
385                 public string UrlPathEncode (string s)
386                 {
387                         if (s == null)
388                                 return null;
389
390                         int idx = s.IndexOf ("?");
391                         string s2 = null;
392                         if (idx != -1) {
393                                 s2 = s.Substring (0, idx-1);
394                                 s2 = UrlEncode (s2) + s.Substring (idx);
395                         } else {
396                                 s2 = UrlEncode (s);
397                         }
398
399                         return s2;
400                 }
401         }
402 }