1 //------------------------------------------------------------------------------
2 // <copyright file="httpserverutility.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6 
7 /*
8  * Server intrinsic used to match ASP's object model
9  *
10  * Copyright (c) 1999 Microsoft Corporation
11  */
12 
13 // Don't entity encode high chars (160 to 256), to fix bugs VSWhidbey 85857/111927
14 //
15 #define ENTITY_ENCODE_HIGH_ASCII_CHARS
16 
17 namespace System.Web {
18     using System.Collections;
19     using System.Collections.Specialized;
20     using System.Globalization;
21     using System.IO;
22     using System.Security.Permissions;
23     using System.Text;
24     using System.Threading;
25     using System.Web.Configuration;
26     using System.Web.Hosting;
27     using System.Web.UI;
28     using System.Web.Util;
29 
30     internal abstract class ErrorFormatterGenerator {
GetErrorFormatter(Exception e)31         internal abstract ErrorFormatter GetErrorFormatter(Exception e);
32     }
33 
34 
35     /// <devdoc>
36     ///    <para>
37     ///       Provides several
38     ///       helper methods that can be used in the processing of Web requests.
39     ///    </para>
40     /// </devdoc>
41     public sealed class HttpServerUtility {
42         private HttpContext _context;
43         private HttpApplication _application;
44 
45         private static IDictionary _cultureCache = Hashtable.Synchronized(new Hashtable());
46 
HttpServerUtility(HttpContext context)47         internal HttpServerUtility(HttpContext context) {
48             _context = context;
49         }
50 
HttpServerUtility(HttpApplication application)51         internal HttpServerUtility(HttpApplication application) {
52             _application = application;
53         }
54 
55         //
56         // Misc ASP compatibility methods
57         //
58 
59 
60         /// <devdoc>
61         ///    <para>
62         ///       Instantiates a COM object identified via a progid.
63         ///    </para>
64         /// </devdoc>
65         [SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
CreateObject(string progID)66         public object CreateObject(string progID) {
67             EnsureHasNotTransitionedToWebSocket();
68 
69             Type type = null;
70             object obj = null;
71 
72             try {
73 #if !FEATURE_PAL // FEATURE_PAL does not enable COM
74                 type = Type.GetTypeFromProgID(progID);
75 #else // !FEATURE_PAL
76                 throw new NotImplementedException("ROTORTODO");
77 #endif // !FEATURE_PAL
78             }
79             catch {
80             }
81 
82             if (type == null) {
83                 throw new HttpException(SR.GetString(SR.Could_not_create_object_of_type, progID));
84             }
85 
86             // Disallow Apartment components in non-compat mode
87             AspCompatApplicationStep.CheckThreadingModel(progID, type.GUID);
88 
89             // Instantiate the object
90             obj = Activator.CreateInstance(type);
91 
92             // For ASP compat: take care of OnPageStart/OnPageEnd
93             AspCompatApplicationStep.OnPageStart(obj);
94 
95             return obj;
96         }
97 
98 
99         /// <devdoc>
100         ///    <para>
101         ///       Instantiates a COM object identified via a Type.
102         ///    </para>
103         /// </devdoc>
104         [SecurityPermission(SecurityAction.Demand, UnmanagedCode=true)]
CreateObject(Type type)105         public object CreateObject(Type type) {
106             EnsureHasNotTransitionedToWebSocket();
107 
108             // Disallow Apartment components in non-compat mode
109             AspCompatApplicationStep.CheckThreadingModel(type.FullName, type.GUID);
110 
111             // Instantiate the object
112             Object obj = Activator.CreateInstance(type);
113 
114             // For ASP compat: take care of OnPageStart/OnPageEnd
115             AspCompatApplicationStep.OnPageStart(obj);
116 
117             return obj;
118         }
119 
120 
121 
122         /// <devdoc>
123         ///    <para>
124         ///       Instantiates a COM object identified via a clsid.
125         ///    </para>
126         /// </devdoc>
127         [SecurityPermission(SecurityAction.Demand, UnmanagedCode=true)]
CreateObjectFromClsid(string clsid)128         public object CreateObjectFromClsid(string clsid) {
129             EnsureHasNotTransitionedToWebSocket();
130 
131             Type type = null;
132             object obj = null;
133 
134             // Create a Guid out of it
135             Guid guid = new Guid(clsid);
136 
137             // Disallow Apartment components in non-compat mode
138             AspCompatApplicationStep.CheckThreadingModel(clsid, guid);
139 
140             try {
141 #if !FEATURE_PAL // FEATURE_PAL does not enable COM
142                 type = Type.GetTypeFromCLSID(guid, null, true /*throwOnError*/);
143 #else // !FEATURE_PAL
144                 throw new NotImplementedException("ROTORTODO");
145 #endif // !FEATURE_PAL
146 
147                 // Instantiate the object
148                 obj = Activator.CreateInstance(type);
149             }
150             catch {
151             }
152 
153             if (obj == null) {
154                 throw new HttpException(
155                     SR.GetString(SR.Could_not_create_object_from_clsid, clsid));
156             }
157 
158             // For ASP compat: take care of OnPageStart/OnPageEnd
159             AspCompatApplicationStep.OnPageStart(obj);
160 
161             return obj;
162         }
163 
164         // Internal static method that returns a read-only, non-user override accounted, CultureInfo object
CreateReadOnlyCultureInfo(string name)165         internal static CultureInfo CreateReadOnlyCultureInfo(string name) {
166             if (!_cultureCache.Contains(name)) {
167                 // To be threadsafe, get the lock before creating
168                 lock (_cultureCache) {
169                     if (_cultureCache[name] == null) {
170                         _cultureCache[name] = CultureInfo.ReadOnly(new CultureInfo(name));
171                     }
172                 }
173             }
174             return (CultureInfo)_cultureCache[name];
175         }
176 
177         // Internal static method that returns a read-only, non-user override accounted, culture specific CultureInfo object
CreateReadOnlySpecificCultureInfo(string name)178         internal static CultureInfo CreateReadOnlySpecificCultureInfo(string name) {
179             if(name.IndexOf('-') > 0) {
180                 return CreateReadOnlyCultureInfo(name);
181             }
182             CultureInfo ci = CultureInfo.CreateSpecificCulture(name);
183             if (!_cultureCache.Contains(ci.Name)) {
184                 //To be threadsafe, get the lock before creating
185                 lock (_cultureCache) {
186                     if (_cultureCache[ci.Name] == null) {
187                         _cultureCache[ci.Name] = CultureInfo.ReadOnly(ci);
188                     }
189                 }
190             }
191             return (CultureInfo)_cultureCache[ci.Name];
192         }
193 
194         // Internal static method that returns a read-only, non-user override accounted, CultureInfo object
CreateReadOnlyCultureInfo(int culture)195         internal static CultureInfo CreateReadOnlyCultureInfo(int culture) {
196             if (!_cultureCache.Contains(culture)) {
197                 // To be threadsafe, get the lock before creating
198                 lock (_cultureCache) {
199                     if (_cultureCache[culture] == null) {
200                         _cultureCache[culture] = CultureInfo.ReadOnly(new CultureInfo(culture));
201                     }
202                 }
203             }
204             return (CultureInfo)_cultureCache[culture];
205         }
206 
207         /// <devdoc>
208         ///    <para>
209         ///       Maps a virtual path to a physical path.
210         ///    </para>
211         /// </devdoc>
MapPath(string path)212         public string MapPath(string path) {
213             if (_context == null)
214                 throw new HttpException(SR.GetString(SR.Server_not_available));
215             // Disable hiding the request so that Server.MapPath works when called from
216             // Application_Start in integrated mode
217             bool unhideRequest = _context.HideRequestResponse;
218             string realPath;
219             try {
220                 if (unhideRequest) {
221                     _context.HideRequestResponse = false;
222                 }
223                 realPath = _context.Request.MapPath(path);
224             }
225             finally {
226                 if (unhideRequest) {
227                     _context.HideRequestResponse = true;
228                 }
229             }
230             return realPath;
231         }
232 
233 
234         /// <devdoc>
235         ///    <para>Returns the last recorded exception.</para>
236         /// </devdoc>
GetLastError()237         public Exception GetLastError() {
238             if (_context != null)
239                 return _context.Error;
240             else if (_application != null)
241                 return _application.LastError;
242             else
243                 return null;
244         }
245 
246 
247         /// <devdoc>
248         ///    <para>Clears the last error.</para>
249         /// </devdoc>
ClearError()250         public void ClearError() {
251             if (_context != null)
252                 _context.ClearError();
253             else if (_application != null)
254                 _application.ClearError();
255         }
256 
257         //
258         // Server.Transfer/Server.Execute -- child requests
259         //
260 
261 
262         /// <devdoc>
263         ///    <para>
264         ///       Executes a new request (using the specified URL path as the target). Unlike
265         ///       the Transfer method, execution of the original page continues after the executed
266         ///       page completes.
267         ///    </para>
268         /// </devdoc>
Execute(string path)269         public void Execute(string path) {
270             Execute(path, null, true /*preserveForm*/);
271         }
272 
273 
274         /// <devdoc>
275         ///    <para>
276         ///       Executes a new request (using the specified URL path as the target). Unlike
277         ///       the Transfer method, execution of the original page continues after the executed
278         ///       page completes.
279         ///    </para>
280         /// </devdoc>
Execute(string path, TextWriter writer)281         public void Execute(string path, TextWriter writer) {
282             Execute(path, writer, true /*preserveForm*/);
283         }
284 
285 
286         /// <devdoc>
287         ///    <para>
288         ///       Executes a new request (using the specified URL path as the target). Unlike
289         ///       the Transfer method, execution of the original page continues after the executed
290         ///       page completes.
291         ///       If preserveForm is false, the QueryString and Form collections are cleared.
292         ///    </para>
293         /// </devdoc>
Execute(string path, bool preserveForm)294         public void Execute(string path, bool preserveForm) {
295             Execute(path, null, preserveForm);
296         }
297 
298 
299         /// <devdoc>
300         ///    <para>
301         ///       Executes a new request (using the specified URL path as the target). Unlike
302         ///       the Transfer method, execution of the original page continues after the executed
303         ///       page completes.
304         ///       If preserveForm is false, the QueryString and Form collections are cleared.
305         ///    </para>
306         /// </devdoc>
Execute(string path, TextWriter writer, bool preserveForm)307         public void Execute(string path, TextWriter writer, bool preserveForm) {
308             EnsureHasNotTransitionedToWebSocket();
309 
310             if (_context == null)
311                 throw new HttpException(SR.GetString(SR.Server_not_available));
312 
313             if (path == null)
314                 throw new ArgumentNullException("path");
315 
316             string queryStringOverride = null;
317             HttpRequest request = _context.Request;
318             HttpResponse response = _context.Response;
319 
320             // Remove potential cookie-less session id (ASURT 100558)
321             path = response.RemoveAppPathModifier(path);
322 
323             // Allow query string override
324             int iqs = path.IndexOf('?');
325             if (iqs >= 0) {
326                 queryStringOverride = path.Substring(iqs+1);
327                 path = path.Substring(0, iqs);
328             }
329 
330             if (!UrlPath.IsValidVirtualPathWithoutProtocol(path)) {
331                 throw new ArgumentException(SR.GetString(SR.Invalid_path_for_child_request, path));
332             }
333 
334             VirtualPath virtualPath = VirtualPath.Create(path);
335 
336             // Find the handler for the path
337 
338             IHttpHandler handler = null;
339 
340             string physPath = request.MapPath(virtualPath);        // get physical path
341             VirtualPath filePath = request.FilePathObject.Combine(virtualPath);    // vpath
342 
343             // Demand read access to the physical path of the target handler
344             InternalSecurityPermissions.FileReadAccess(physPath).Demand();
345 
346             // We need to Assert since there typically is user code on the stack (VSWhidbey 270965)
347             if (HttpRuntime.IsLegacyCas) {
348                 InternalSecurityPermissions.Unrestricted.Assert();
349             }
350 
351             try {
352                 // paths that ends with . are disallowed as they are used to get around
353                 // extension mappings and server source as static file
354                 if (StringUtil.StringEndsWith(virtualPath.VirtualPathString, '.'))
355                     throw new HttpException(404, String.Empty);
356 
357                 bool useAppConfig = !filePath.IsWithinAppRoot;
358 
359                 using (new DisposableHttpContextWrapper(_context)) {
360 
361                     try {
362                         // We need to increase the depth when calling MapHttpHandler,
363                         // since PageHandlerFactory relies on it
364                         _context.ServerExecuteDepth++;
365 
366                         if (_context.WorkerRequest is IIS7WorkerRequest) {
367                             handler = _context.ApplicationInstance.MapIntegratedHttpHandler(
368                                 _context,
369                                 request.RequestType,
370                                 filePath,
371                                 physPath,
372                                 useAppConfig,
373                                 true /*convertNativeStaticFileModule*/);
374                         }
375                         else {
376                             handler = _context.ApplicationInstance.MapHttpHandler(
377                                 _context,
378                                 request.RequestType,
379                                 filePath,
380                                 physPath,
381                                 useAppConfig);
382                         }
383                     }
384                     finally {
385                         _context.ServerExecuteDepth--;
386                     }
387                 }
388             }
389             catch (Exception e) {
390                 // 500 errors (compilation errors) get preserved
391                 if (e is HttpException) {
392                     int code = ((HttpException)e).GetHttpCode();
393 
394                     if (code != 500 && code != 404) {
395                         e = null;
396                     }
397                 }
398 
399                 throw new HttpException(SR.GetString(SR.Error_executing_child_request_for_path, path), e);
400             }
401 
402             ExecuteInternal(handler, writer, preserveForm, true /*setPreviousPage*/,
403                 virtualPath, filePath, physPath, null, queryStringOverride);
404         }
405 
406 
Execute(IHttpHandler handler, TextWriter writer, bool preserveForm)407         public void Execute(IHttpHandler handler, TextWriter writer, bool preserveForm) {
408             if (_context == null)
409                 throw new HttpException(SR.GetString(SR.Server_not_available));
410 
411             Execute(handler, writer, preserveForm, true /*setPreviousPage*/);
412         }
413 
Execute(IHttpHandler handler, TextWriter writer, bool preserveForm, bool setPreviousPage)414         internal void Execute(IHttpHandler handler, TextWriter writer, bool preserveForm, bool setPreviousPage) {
415             HttpRequest request = _context.Request;
416             VirtualPath filePath = request.CurrentExecutionFilePathObject;
417             string physicalPath = request.MapPath(filePath);
418 
419             ExecuteInternal(handler, writer, preserveForm, setPreviousPage,
420                 null, filePath, physicalPath, null, null);
421         }
422 
ExecuteInternal(IHttpHandler handler, TextWriter writer, bool preserveForm, bool setPreviousPage, VirtualPath path, VirtualPath filePath, string physPath, Exception error, string queryStringOverride)423         private void ExecuteInternal(IHttpHandler handler, TextWriter writer, bool preserveForm, bool setPreviousPage,
424             VirtualPath path, VirtualPath filePath, string physPath, Exception error, string queryStringOverride) {
425 
426             EnsureHasNotTransitionedToWebSocket();
427 
428             if (handler == null)
429                 throw new ArgumentNullException("handler");
430 
431             HttpRequest request = _context.Request;
432             HttpResponse response = _context.Response;
433             HttpApplication app = _context.ApplicationInstance;
434 
435             HttpValueCollection savedForm = null;
436             VirtualPath savedCurrentExecutionFilePath = null;
437             string savedQueryString = null;
438             TextWriter savedOutputWriter = null;
439             AspNetSynchronizationContextBase savedSyncContext = null;
440 
441             // Transaction wouldn't flow into ASPCOMPAT mode -- need to report an error
442             VerifyTransactionFlow(handler);
443 
444             // create new trace context
445             _context.PushTraceContext();
446 
447             // set the new handler as the current handler
448             _context.SetCurrentHandler(handler);
449 
450             // because we call this synchrnously async operations must be disabled
451             bool originalSyncContextWasEnabled = _context.SyncContext.Enabled;
452             _context.SyncContext.Disable();
453 
454             // Execute the handler
455             try {
456                 try {
457                     _context.ServerExecuteDepth++;
458 
459                     savedCurrentExecutionFilePath = request.SwitchCurrentExecutionFilePath(filePath);
460 
461                     if (!preserveForm) {
462                         savedForm = request.SwitchForm(new HttpValueCollection());
463 
464                         // Clear out the query string, but honor overrides
465                         if (queryStringOverride == null)
466                             queryStringOverride = String.Empty;
467                     }
468 
469                     // override query string if requested
470                     if (queryStringOverride != null) {
471                         savedQueryString = request.QueryStringText;
472                         request.QueryStringText = queryStringOverride;
473                     }
474 
475                     // capture output if requested
476                     if (writer != null)
477                         savedOutputWriter = response.SwitchWriter(writer);
478 
479                     Page targetPage = handler as Page;
480                     if (targetPage != null) {
481                         if (setPreviousPage) {
482                             // Set the previousPage of the new Page as the previous Page
483                             targetPage.SetPreviousPage(_context.PreviousHandler as Page);
484                         }
485 
486                         Page sourcePage = _context.Handler as Page;
487 
488 #pragma warning disable 0618    // To avoid deprecation warning
489                         // If the source page of the transfer has smart nav on,
490                         // always do as if the destination has it too (ASURT 97732)
491                         if (sourcePage != null && sourcePage.SmartNavigation)
492                             targetPage.SmartNavigation = true;
493 #pragma warning restore 0618
494 
495                         // If the target page is async need to save/restore sync context
496                         if (targetPage is IHttpAsyncHandler) {
497                             savedSyncContext = _context.InstallNewAspNetSynchronizationContext();
498                         }
499                     }
500 
501                     if ((handler is StaticFileHandler || handler is DefaultHttpHandler) &&
502                        !DefaultHttpHandler.IsClassicAspRequest(filePath.VirtualPathString)) {
503                         // cannot apply static files handler directly
504                         // -- it would dump the source of the current page
505                         // instead just dump the file content into response
506                         try {
507                             response.WriteFile(physPath);
508                         }
509                         catch {
510                             // hide the real error as it could be misleading
511                             // in case of mismapped requests like /foo.asmx/bar
512                             error = new HttpException(404, String.Empty);
513                         }
514                     }
515                     else if (!(handler is Page)) {
516                         // disallow anything but pages
517                         error = new HttpException(404, String.Empty);
518                     }
519                     else if (handler is IHttpAsyncHandler) {
520                         // Asynchronous handler
521 
522                         // suspend cancellable period (don't abort this thread while
523                         // we wait for another to finish)
524                         bool isCancellable =  _context.IsInCancellablePeriod;
525                         if (isCancellable)
526                             _context.EndCancellablePeriod();
527 
528                         try {
529                             IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler)handler;
530 
531                             if (!AppSettings.UseTaskFriendlySynchronizationContext) {
532                                 // Legacy code path: behavior ASP.NET <= 4.0
533 
534                                 IAsyncResult ar = asyncHandler.BeginProcessRequest(_context, null, null);
535 
536                                 // wait for completion
537                                 if (!ar.IsCompleted) {
538                                     // suspend app lock while waiting
539                                     bool needToRelock = false;
540 
541                                     try {
542                                         try { }
543                                         finally {
544                                             _context.SyncContext.DisassociateFromCurrentThread();
545                                             needToRelock = true;
546                                         }
547 
548                                         WaitHandle h = ar.AsyncWaitHandle;
549 
550                                         if (h != null) {
551                                             h.WaitOne();
552                                         }
553                                         else {
554                                             while (!ar.IsCompleted)
555                                                 Thread.Sleep(1);
556                                         }
557                                     }
558                                     finally {
559                                         if (needToRelock) {
560                                             _context.SyncContext.AssociateWithCurrentThread();
561                                         }
562                                     }
563                                 }
564 
565                                 // end the async operation (get error if any)
566 
567                                 try {
568                                     asyncHandler.EndProcessRequest(ar);
569                                 }
570                                 catch (Exception e) {
571                                     error = e;
572                                 }
573                             }
574                             else {
575                                 // New code path: behavior ASP.NET >= 4.5
576                                 IAsyncResult ar;
577                                 bool blockedThread;
578 
579                                 using (CountdownEvent countdownEvent = new CountdownEvent(1)) {
580                                     using (_context.SyncContext.AcquireThreadLock()) {
581                                         // Kick off the asynchronous operation
582                                         ar = asyncHandler.BeginProcessRequest(_context,
583                                            cb: _ => { countdownEvent.Signal(); },
584                                            extraData: null);
585                                     }
586 
587                                     // The callback passed to BeginProcessRequest will signal the CountdownEvent.
588                                     // The Wait() method blocks until the callback executes; no-ops if the operation completed synchronously.
589                                     blockedThread = !countdownEvent.IsSet;
590                                     countdownEvent.Wait();
591                                 }
592 
593                                 // end the async operation (get error if any)
594 
595                                 try {
596                                     using (_context.SyncContext.AcquireThreadLock()) {
597                                         asyncHandler.EndProcessRequest(ar);
598                                     }
599 
600                                     // If we blocked the thread, YSOD the request to display a diagnostic message.
601                                     if (blockedThread && !_context.SyncContext.AllowAsyncDuringSyncStages) {
602                                         throw new InvalidOperationException(SR.GetString(SR.Server_execute_blocked_on_async_handler));
603                                     }
604                                 }
605                                 catch (Exception e) {
606                                     error = e;
607                                 }
608                             }
609                         }
610                         finally {
611                             // resume cancelleable period
612                             if (isCancellable)
613                                 _context.BeginCancellablePeriod();
614                         }
615                     }
616                     else {
617                         // Synchronous handler
618 
619                         using (new DisposableHttpContextWrapper(_context)) {
620                             try {
621                                 handler.ProcessRequest(_context);
622                             }
623                             catch (Exception e) {
624                                 error = e;
625                             }
626                         }
627                     }
628                 }
629                 finally {
630                     _context.ServerExecuteDepth--;
631 
632                     // Restore the handlers;
633                     _context.RestoreCurrentHandler();
634 
635                     // restore output writer
636                     if (savedOutputWriter != null)
637                         response.SwitchWriter(savedOutputWriter);
638 
639                     // restore overriden query string
640                     if (queryStringOverride != null && savedQueryString != null)
641                         request.QueryStringText = savedQueryString;
642 
643                     if (savedForm != null)
644                         request.SwitchForm(savedForm);
645 
646                     request.SwitchCurrentExecutionFilePath(savedCurrentExecutionFilePath);
647 
648                     if (savedSyncContext != null) {
649                         _context.RestoreSavedAspNetSynchronizationContext(savedSyncContext);
650                     }
651 
652                     if (originalSyncContextWasEnabled) {
653                         _context.SyncContext.Enable();
654                     }
655 
656                     // restore trace context
657                     _context.PopTraceContext();
658                 }
659             }
660             catch { // Protect against exception filters
661                 throw;
662             }
663 
664             // Report any error
665             if (error != null) {
666                 // suppress errors with HTTP codes (for child requests they mislead more than help)
667                 if (error is HttpException && ((HttpException)error).GetHttpCode() != 500)
668                     error = null;
669 
670                 if (path != null)
671                     throw new HttpException(SR.GetString(SR.Error_executing_child_request_for_path, path), error);
672 
673                 throw new HttpException(SR.GetString(SR.Error_executing_child_request_for_handler, handler.GetType().ToString()), error);
674             }
675         }
676 
677 
678         /// <devdoc>
679         ///    <para>
680         ///       Terminates execution of the current page and begins execution of a new
681         ///       request using the supplied URL path.
682         ///       If preserveForm is false, the QueryString and Form collections are cleared.
683         ///    </para>
684         /// </devdoc>
Transfer(string path, bool preserveForm)685         public void Transfer(string path, bool preserveForm) {
686             Page page = _context.Handler as Page;
687             if ((page != null) && page.IsCallback) {
688                 throw new ApplicationException(SR.GetString(SR.Transfer_not_allowed_in_callback));
689             }
690 
691             // execute child request
692 
693             Execute(path, null, preserveForm);
694 
695             // suppress the remainder of the current one
696 
697             _context.Response.End();
698         }
699 
700 
701         /// <devdoc>
702         ///    <para>
703         ///       Terminates execution of the current page and begins execution of a new
704         ///       request using the supplied URL path.
705         ///    </para>
706         /// </devdoc>
Transfer(string path)707         public void Transfer(string path) {
708             // Make sure the transfer is not treated as a postback, which could cause a stack
709             // overflow if the user doesn't expect it (VSWhidbey 181013).
710             // If the use *does* want it treated as a postback, they can call Transfer(path, true).
711             bool savedPreventPostback = _context.PreventPostback;
712             _context.PreventPostback = true;
713 
714             Transfer(path, true /*preserveForm*/);
715 
716             _context.PreventPostback = savedPreventPostback;
717         }
718 
719 
Transfer(IHttpHandler handler, bool preserveForm)720         public void Transfer(IHttpHandler handler, bool preserveForm) {
721             Page page = handler as Page;
722             if ((page != null) && page.IsCallback) {
723                 throw new ApplicationException(SR.GetString(SR.Transfer_not_allowed_in_callback));
724             }
725 
726             Execute(handler, null, preserveForm);
727 
728             // suppress the remainder of the current one
729 
730             _context.Response.End();
731         }
732 
TransferRequest(string path)733         public void TransferRequest(string path)
734         {
735             TransferRequest(path, false, null, null, preserveUser: true);
736         }
737 
TransferRequest(string path, bool preserveForm)738         public void TransferRequest(string path, bool preserveForm)
739         {
740             TransferRequest(path, preserveForm, null, null, preserveUser: true);
741         }
742 
TransferRequest(string path, bool preserveForm, string method, NameValueCollection headers)743         public void TransferRequest(string path, bool preserveForm, string method, NameValueCollection headers) {
744             TransferRequest(path, preserveForm, method, headers, preserveUser: true);
745         }
746 
TransferRequest(string path, bool preserveForm, string method, NameValueCollection headers, bool preserveUser)747         public void TransferRequest(string path, bool preserveForm, string method, NameValueCollection headers, bool preserveUser) {
748             EnsureHasNotTransitionedToWebSocket();
749 
750             if (!HttpRuntime.UseIntegratedPipeline) {
751                 throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode));
752             }
753 
754             if (_context == null) {
755                 throw new HttpException(SR.GetString(SR.Server_not_available));
756             }
757 
758             if (path == null) {
759                 throw new ArgumentNullException("path");
760             }
761 
762             IIS7WorkerRequest wr = _context.WorkerRequest as IIS7WorkerRequest;
763             HttpRequest request = _context.Request;
764             HttpResponse response = _context.Response;
765 
766             if (wr == null) {
767                 throw new HttpException(SR.GetString(SR.Server_not_available));
768             }
769 
770             // Remove potential cookie-less session id (ASURT 100558)
771             path = response.RemoveAppPathModifier(path);
772 
773             // Extract query string if specified
774             String qs = null;
775             int iqs = path.IndexOf('?');
776             if (iqs >= 0) {
777                 qs = (iqs < path.Length-1) ? path.Substring(iqs+1) : String.Empty;
778                 path = path.Substring(0, iqs);
779             }
780 
781             if (!UrlPath.IsValidVirtualPathWithoutProtocol(path)) {
782                 throw new ArgumentException(SR.GetString(SR.Invalid_path_for_child_request, path));
783             }
784 
785             VirtualPath virtualPath = request.FilePathObject.Combine(VirtualPath.Create(path));
786 
787             //  Schedule the child execution
788             wr.ScheduleExecuteUrl( virtualPath.VirtualPathString,
789                                    qs,
790                                    method,
791                                    preserveForm,
792                                    preserveForm ? request.EntityBody : null,
793                                    headers,
794                                    preserveUser);
795 
796             // force the completion of the current request so that the
797             // child execution can be performed immediately after unwind
798             _context.ApplicationInstance.EnsureReleaseState();
799 
800             // DevDiv Bugs 162750: IIS7 Integrated Mode:  TransferRequest performance issue
801             // Instead of calling Response.End we call HttpApplication.CompleteRequest()
802             _context.ApplicationInstance.CompleteRequest();
803         }
804 
VerifyTransactionFlow(IHttpHandler handler)805         private void VerifyTransactionFlow(IHttpHandler handler) {
806             Page topPage = _context.Handler as Page;
807             Page childPage = handler as Page;
808 
809             if (childPage != null && childPage.IsInAspCompatMode && // child page aspcompat
810                 topPage != null && !topPage.IsInAspCompatMode &&    // top page is not aspcompat
811                 Transactions.Utils.IsInTransaction) {               // we are in transaction
812 
813                 throw new HttpException(SR.GetString(SR.Transacted_page_calls_aspcompat));
814             }
815         }
816 
817         //
818         // Static method to execute a request outside of HttpContext and capture the response
819         //
820 
ExecuteLocalRequestAndCaptureResponse(String path, TextWriter writer, ErrorFormatterGenerator errorFormatterGenerator)821         internal static void ExecuteLocalRequestAndCaptureResponse(String path, TextWriter writer,
822                                                                 ErrorFormatterGenerator errorFormatterGenerator) {
823             HttpRequest request = new HttpRequest(
824                                           VirtualPath.CreateAbsolute(path),
825                                           String.Empty);
826 
827             HttpResponse response = new HttpResponse(writer);
828 
829             HttpContext context = new HttpContext(request, response);
830 
831             HttpApplication app = HttpApplicationFactory.GetApplicationInstance(context) as HttpApplication;
832             context.ApplicationInstance = app;
833 
834             try {
835                 context.Server.Execute(path);
836             }
837             catch (HttpException e) {
838                 if (errorFormatterGenerator != null) {
839                     context.Response.SetOverrideErrorFormatter(errorFormatterGenerator.GetErrorFormatter(e));
840                 }
841 
842                 context.Response.ReportRuntimeError(e, false, true);
843             }
844             finally {
845                 if (app != null) {
846                     context.ApplicationInstance = null;
847                     HttpApplicationFactory.RecycleApplicationInstance(app);
848                 }
849             }
850         }
851 
852         //
853         // Computer name
854         //
855 
856         private static object _machineNameLock = new object();
857         private static string _machineName;
858         private const int _maxMachineNameLength = 256;
859 
860 
861         /// <devdoc>
862         ///    <para>
863         ///       Gets
864         ///       the server machine name.
865         ///    </para>
866         /// </devdoc>
867         public string MachineName {
868             [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)]
869             get {
870                 return GetMachineNameInternal();
871             }
872         }
873 
GetMachineNameInternal()874         internal static string GetMachineNameInternal()
875         {
876             if (_machineName != null)
877                 return _machineName;
878             lock (_machineNameLock)
879             {
880                 if (_machineName != null)
881                     return _machineName;
882 
883                 StringBuilder   buf = new StringBuilder (_maxMachineNameLength);
884                 int             len = _maxMachineNameLength;
885 
886                 if (UnsafeNativeMethods.GetComputerName (buf, ref len) == 0)
887                     throw new HttpException (SR.GetString(SR.Get_computer_name_failed));
888 
889                 _machineName = buf.ToString();
890             }
891             return _machineName;
892         }
893 
894         //
895         // Request Timeout
896         //
897 
898 
899         /// <devdoc>
900         ///    <para>
901         ///       Request timeout in seconds
902         ///    </para>
903         /// </devdoc>
904         public int ScriptTimeout {
905             get {
906                 if (_context != null) {
907                     return Convert.ToInt32(_context.Timeout.TotalSeconds);
908                 }
909                 else {
910                     return HttpRuntimeSection.DefaultExecutionTimeout;
911                 }
912             }
913 
914             [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)]
915             set {
916                 if (_context == null)
917                     throw new HttpException(SR.GetString(SR.Server_not_available));
918                 if (value <= 0)
919                     throw new ArgumentOutOfRangeException("value");
920                 _context.Timeout = new TimeSpan(0, 0, value);
921             }
922         }
923 
924         //
925         // Encoding / Decoding -- wrappers for HttpUtility
926         //
927 
928 
929         /// <devdoc>
930         ///    <para>
931         ///       HTML
932         ///       decodes a given string and
933         ///       returns the decoded string.
934         ///    </para>
935         /// </devdoc>
HtmlDecode(string s)936         public string HtmlDecode(string s) {
937             return HttpUtility.HtmlDecode(s);
938         }
939 
940 
941         /// <devdoc>
942         ///    <para>
943         ///       HTML
944         ///       decode a string and send the result to a TextWriter output
945         ///       stream.
946         ///    </para>
947         /// </devdoc>
HtmlDecode(string s, TextWriter output)948         public void HtmlDecode(string s, TextWriter output) {
949             HttpUtility.HtmlDecode(s, output);
950         }
951 
952 
953         /// <devdoc>
954         ///    <para>
955         ///       HTML
956         ///       encodes a given string and
957         ///       returns the encoded string.
958         ///    </para>
959         /// </devdoc>
HtmlEncode(string s)960         public string HtmlEncode(string s) {
961             return HttpUtility.HtmlEncode(s);
962         }
963 
964 
965         /// <devdoc>
966         ///    <para>
967         ///       HTML
968         ///       encodes
969         ///       a string and returns the output to a TextWriter stream of output.
970         ///    </para>
971         /// </devdoc>
HtmlEncode(string s, TextWriter output)972         public void HtmlEncode(string s, TextWriter output) {
973             HttpUtility.HtmlEncode(s, output);
974         }
975 
976 
977         /// <devdoc>
978         ///    <para>
979         ///       URL
980         ///       encodes a given
981         ///       string and returns the encoded string.
982         ///    </para>
983         /// </devdoc>
UrlEncode(string s)984         public string UrlEncode(string s) {
985             Encoding e = (_context != null) ? _context.Response.ContentEncoding : Encoding.UTF8;
986             return HttpUtility.UrlEncode(s, e);
987         }
988 
989 
990         /// <devdoc>
991         ///    <para>
992         ///       URL encodes a path portion of a URL string and returns the encoded string.
993         ///    </para>
994         /// </devdoc>
UrlPathEncode(string s)995         public string UrlPathEncode(string s) {
996             return HttpUtility.UrlPathEncode(s);
997         }
998 
999 
1000         /// <devdoc>
1001         ///    <para>
1002         ///       URL
1003         ///       encodes
1004         ///       a string and returns the output to a TextWriter output stream.
1005         ///    </para>
1006         /// </devdoc>
UrlEncode(string s, TextWriter output)1007         public void UrlEncode(string s, TextWriter output) {
1008             if (s != null)
1009                 output.Write(UrlEncode(s));
1010         }
1011 
1012 
1013         /// <devdoc>
1014         ///    <para>
1015         ///       URL decodes a string and returns the output in a string.
1016         ///    </para>
1017         /// </devdoc>
UrlDecode(string s)1018         public string UrlDecode(string s) {
1019             Encoding e = (_context != null) ? _context.Request.ContentEncoding : Encoding.UTF8;
1020             return HttpUtility.UrlDecode(s, e);
1021         }
1022 
1023 
1024         /// <devdoc>
1025         ///    <para>
1026         ///       URL decodes a string and returns the output as a TextWriter output
1027         ///       stream.
1028         ///    </para>
1029         /// </devdoc>
UrlDecode(string s, TextWriter output)1030         public void UrlDecode(string s, TextWriter output) {
1031             if (s != null)
1032                 output.Write(UrlDecode(s));
1033         }
1034 
1035         /////////////////////////////////////////////////////////////////////////////
1036         /////////////////////////////////////////////////////////////////////////////
1037         /////////////////////////////////////////////////////////////////////////////
1038 
UrlTokenEncode(byte [] input)1039         static public string UrlTokenEncode(byte [] input)
1040         {
1041             return HttpEncoder.Current.UrlTokenEncode(input);
1042         }
1043 
1044         /////////////////////////////////////////////////////////////////////////////
1045         /////////////////////////////////////////////////////////////////////////////
1046         /////////////////////////////////////////////////////////////////////////////
1047 
UrlTokenDecode(string input)1048         static public byte [] UrlTokenDecode(string input) {
1049             return HttpEncoder.Current.UrlTokenDecode(input);
1050         }
1051 
1052         // helper that throws an exception if we have transitioned the current request to a WebSocket request
EnsureHasNotTransitionedToWebSocket()1053         internal void EnsureHasNotTransitionedToWebSocket() {
1054             if (_context != null) {
1055                 _context.EnsureHasNotTransitionedToWebSocket();
1056             }
1057         }
1058     }
1059 
1060 
1061     /// <devdoc>
1062     /// </devdoc>
1063 
1064     // VSWhidbey 473228 - removed link demand from HttpUtility for ClickOnce scenario
1065     public sealed class HttpUtility {
1066 
HttpUtility()1067         public HttpUtility () {}
1068 
1069 		//////////////////////////////////////////////////////////////////////////
1070         //
1071         //  HTML Encoding / Decoding
1072         //
1073 
1074 
1075         /// <devdoc>
1076         ///    <para>
1077         ///       HTML decodes a string and returns the decoded string.
1078         ///    </para>
1079         /// </devdoc>
HtmlDecode(string s)1080         public static string HtmlDecode(string s) {
1081             return HttpEncoder.Current.HtmlDecode(s);
1082         }
1083 
1084 
1085         /// <devdoc>
1086         ///    <para>
1087         ///       HTML decode a string and send the result to a TextWriter output stream.
1088         ///    </para>
1089         /// </devdoc>
HtmlDecode(string s, TextWriter output)1090         public static void HtmlDecode(string s, TextWriter output) {
1091             HttpEncoder.Current.HtmlDecode(s, output);
1092         }
1093 
1094 
1095         /// <devdoc>
1096         ///    <para>
1097         ///       HTML encodes a string and returns the encoded string.
1098         ///    </para>
1099         /// </devdoc>
HtmlEncode(String s)1100         public static String HtmlEncode(String s) {
1101             return HttpEncoder.Current.HtmlEncode(s);
1102         }
1103 
1104 
1105         /// <devdoc>
1106         ///    <para>
1107         ///       HTML encodes an object's string representation and returns the encoded string.
1108         ///       If the object implements IHtmlString, don't encode it
1109         ///    </para>
1110         /// </devdoc>
HtmlEncode(object value)1111         public static String HtmlEncode(object value) {
1112             if (value == null) {
1113                 // Return null to be consistent with HtmlEncode(string)
1114                 return null;
1115             }
1116 
1117             var htmlString = value as IHtmlString;
1118             if (htmlString != null) {
1119                 return htmlString.ToHtmlString();
1120             }
1121 
1122             return HtmlEncode(Convert.ToString(value, CultureInfo.CurrentCulture));
1123         }
1124 
1125 
1126         /// <devdoc>
1127         ///    <para>
1128         ///       HTML encodes a string and returns the output to a TextWriter stream of
1129         ///       output.
1130         ///    </para>
1131         /// </devdoc>
HtmlEncode(String s, TextWriter output)1132         public static void HtmlEncode(String s, TextWriter output) {
1133             HttpEncoder.Current.HtmlEncode(s, output);
1134         }
1135 
1136 
1137         /// <devdoc>
1138         ///    <para>
1139         ///       Encodes a string to make it a valid HTML attribute and returns the encoded string.
1140         ///    </para>
1141         /// </devdoc>
HtmlAttributeEncode(String s)1142         public static String HtmlAttributeEncode(String s) {
1143             return HttpEncoder.Current.HtmlAttributeEncode(s);
1144         }
1145 
1146 
1147         /// <devdoc>
1148         ///    <para>
1149         ///       Encodes a string to make it a valid HTML attribute and returns the output
1150         ///       to a TextWriter stream of
1151         ///       output.
1152         ///    </para>
1153         /// </devdoc>
HtmlAttributeEncode(String s, TextWriter output)1154         public static void HtmlAttributeEncode(String s, TextWriter output) {
1155             HttpEncoder.Current.HtmlAttributeEncode(s, output);
1156         }
1157 
1158 
FormatPlainTextSpacesAsHtml(string s)1159         internal static string FormatPlainTextSpacesAsHtml(string s) {
1160             if (s == null) {
1161                 return null;
1162             }
1163 
1164             StringBuilder builder = new StringBuilder();
1165             StringWriter writer = new StringWriter(builder);
1166 
1167             int cb = s.Length;
1168 
1169             for (int i = 0; i < cb; i++) {
1170                 char ch = s[i];
1171                 if(ch == ' ') {
1172                     writer.Write("&nbsp;");
1173                 }
1174                 else {
1175                     writer.Write(ch);
1176                 }
1177             }
1178             return builder.ToString();
1179         }
1180 
FormatPlainTextAsHtml(String s)1181         internal static String FormatPlainTextAsHtml(String s) {
1182             if (s == null)
1183                 return null;
1184 
1185             StringBuilder builder = new StringBuilder();
1186             StringWriter writer = new StringWriter(builder);
1187 
1188             FormatPlainTextAsHtml(s, writer);
1189 
1190             return builder.ToString();
1191         }
1192 
FormatPlainTextAsHtml(String s, TextWriter output)1193         internal static void FormatPlainTextAsHtml(String s, TextWriter output) {
1194             if (s == null)
1195                 return;
1196 
1197             int cb = s.Length;
1198 
1199             char prevCh = '\0';
1200 
1201             for (int i=0; i<cb; i++) {
1202                 char ch = s[i];
1203                 switch (ch) {
1204                     case '<':
1205                         output.Write("&lt;");
1206                         break;
1207                     case '>':
1208                         output.Write("&gt;");
1209                         break;
1210                     case '"':
1211                         output.Write("&quot;");
1212                         break;
1213                     case '&':
1214                         output.Write("&amp;");
1215                         break;
1216                     case ' ':
1217                         if (prevCh == ' ')
1218                             output.Write("&nbsp;");
1219                         else
1220                             output.Write(ch);
1221                         break;
1222                     case '\r':
1223                         // Ignore \r, only handle \n
1224                         break;
1225                     case '\n':
1226                         output.Write("<br>");
1227                         break;
1228 
1229                     //
1230                     default:
1231 #if ENTITY_ENCODE_HIGH_ASCII_CHARS
1232                         // The seemingly arbitrary 160 comes from RFC
1233                         if (ch >= 160 && ch < 256) {
1234                             output.Write("&#");
1235                             output.Write(((int)ch).ToString(NumberFormatInfo.InvariantInfo));
1236                             output.Write(';');
1237                             break;
1238                         }
1239 #endif // ENTITY_ENCODE_HIGH_ASCII_CHARS
1240 
1241                         output.Write(ch);
1242                         break;
1243                 }
1244 
1245                 prevCh = ch;
1246             }
1247         }
1248 
1249 
1250         //////////////////////////////////////////////////////////////////////////
1251         //
1252         //  ASII encode - everything all non-7-bit to '?'
1253         //
1254 
1255         /*internal static String AsciiEncode(String s) {
1256             if (s == null)
1257                 return null;
1258 
1259             StringBuilder sb = new StringBuilder(s.Length);
1260 
1261             for (int i = 0; i < s.Length; i++) {
1262                 char ch = s[i];
1263                 if (((ch & 0xff80) != 0) || (ch < ' ' && ch != '\r' && ch != '\n' && ch != '\t'))
1264                     ch = '?';
1265                 sb.Append(ch);
1266             }
1267 
1268             return sb.ToString();
1269         }*/
1270 
1271 
1272         //
1273         //  Query string parsing support
1274         //
1275 
ParseQueryString(string query)1276         public static NameValueCollection ParseQueryString(string query) {
1277             return ParseQueryString(query, Encoding.UTF8);
1278         }
1279 
ParseQueryString(string query, Encoding encoding)1280         public static NameValueCollection ParseQueryString(string query, Encoding encoding) {
1281             if (query == null) {
1282                 throw new ArgumentNullException("query");
1283             }
1284 
1285             if (encoding == null) {
1286                 throw new ArgumentNullException("encoding");
1287             }
1288 
1289             if (query.Length > 0 && query[0] == '?') {
1290                 query = query.Substring(1);
1291             }
1292 
1293             return new HttpValueCollection(query, false, true, encoding);
1294         }
1295 
1296         //////////////////////////////////////////////////////////////////////////
1297         //
1298         //  URL decoding / encoding
1299         //
1300         //////////////////////////////////////////////////////////////////////////
1301 
1302         //
1303         //  Public static methods
1304         //
1305 
1306 
1307         /// <devdoc>
1308         ///    <para>[To be supplied.]</para>
1309         /// </devdoc>
UrlEncode(string str)1310         public static string UrlEncode(string str) {
1311             if (str == null)
1312                 return null;
1313             return UrlEncode(str, Encoding.UTF8);
1314         }
1315 
1316 
1317         /// <devdoc>
1318         ///    <para>
1319         ///       URL encodes a path portion of a URL string and returns the encoded string.
1320         ///    </para>
1321         /// </devdoc>
UrlPathEncode(string str)1322         public static string UrlPathEncode(string str) {
1323             return HttpEncoder.Current.UrlPathEncode(str);
1324         }
1325 
AspCompatUrlEncode(string s)1326         internal static string AspCompatUrlEncode(string s) {
1327             s = UrlEncode(s);
1328             s = s.Replace("!", "%21");
1329             s = s.Replace("*", "%2A");
1330             s = s.Replace("(", "%28");
1331             s = s.Replace(")", "%29");
1332             s = s.Replace("-", "%2D");
1333             s = s.Replace(".", "%2E");
1334             s = s.Replace("_", "%5F");
1335             s = s.Replace("\\", "%5C");
1336             return s;
1337         }
1338 
1339 
1340         /// <devdoc>
1341         ///    <para>[To be supplied.]</para>
1342         /// </devdoc>
UrlEncode(string str, Encoding e)1343         public static string UrlEncode(string str, Encoding e) {
1344             if (str == null)
1345                 return null;
1346             return Encoding.ASCII.GetString(UrlEncodeToBytes(str, e));
1347         }
1348 
1349         //  Helper to encode the non-ASCII url characters only
UrlEncodeNonAscii(string str, Encoding e)1350         internal static String UrlEncodeNonAscii(string str, Encoding e) {
1351             return HttpEncoder.Current.UrlEncodeNonAscii(str, e);
1352         }
1353 
1354         /// <devdoc>
1355         ///    <para>[To be supplied.]</para>
1356         /// </devdoc>
UrlEncode(byte[] bytes)1357         public static string UrlEncode(byte[] bytes) {
1358             if (bytes == null)
1359                 return null;
1360             return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes));
1361         }
1362 
1363 
1364         /// <devdoc>
1365         ///    <para>[To be supplied.]</para>
1366         /// </devdoc>
UrlEncode(byte[] bytes, int offset, int count)1367         public static string UrlEncode(byte[] bytes, int offset, int count) {
1368             if (bytes == null)
1369                 return null;
1370             return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, offset, count));
1371         }
1372 
1373 
1374         /// <devdoc>
1375         ///    <para>[To be supplied.]</para>
1376         /// </devdoc>
UrlEncodeToBytes(string str)1377         public static byte[] UrlEncodeToBytes(string str) {
1378             if (str == null)
1379                 return null;
1380             return UrlEncodeToBytes(str, Encoding.UTF8);
1381         }
1382 
1383 
1384         /// <devdoc>
1385         ///    <para>[To be supplied.]</para>
1386         /// </devdoc>
UrlEncodeToBytes(string str, Encoding e)1387         public static byte[] UrlEncodeToBytes(string str, Encoding e) {
1388             if (str == null)
1389                 return null;
1390             byte[] bytes = e.GetBytes(str);
1391             return HttpEncoder.Current.UrlEncode(bytes, 0, bytes.Length, false /* alwaysCreateNewReturnValue */);
1392         }
1393 
1394 
1395         /// <devdoc>
1396         ///    <para>[To be supplied.]</para>
1397         /// </devdoc>
UrlEncodeToBytes(byte[] bytes)1398         public static byte[] UrlEncodeToBytes(byte[] bytes) {
1399             if (bytes == null)
1400                 return null;
1401             return UrlEncodeToBytes(bytes, 0, bytes.Length);
1402         }
1403 
1404 
1405         /// <devdoc>
1406         ///    <para>[To be supplied.]</para>
1407         /// </devdoc>
UrlEncodeToBytes(byte[] bytes, int offset, int count)1408         public static byte[] UrlEncodeToBytes(byte[] bytes, int offset, int count) {
1409             return HttpEncoder.Current.UrlEncode(bytes, offset, count, true /* alwaysCreateNewReturnValue */);
1410         }
1411 
1412 
1413         /// <devdoc>
1414         ///    <para>[To be supplied.]</para>
1415         /// </devdoc>
1416         [Obsolete("This method produces non-standards-compliant output and has interoperability issues. The preferred alternative is UrlEncode(String).")]
UrlEncodeUnicode(string str)1417         public static string UrlEncodeUnicode(string str) {
1418             return HttpEncoder.Current.UrlEncodeUnicode(str, false /* ignoreAscii */);
1419         }
1420 
1421 
1422         /// <devdoc>
1423         ///    <para>[To be supplied.]</para>
1424         /// </devdoc>
1425         [Obsolete("This method produces non-standards-compliant output and has interoperability issues. The preferred alternative is UrlEncodeToBytes(String).")]
UrlEncodeUnicodeToBytes(string str)1426         public static byte[] UrlEncodeUnicodeToBytes(string str) {
1427             if (str == null)
1428                 return null;
1429             return Encoding.ASCII.GetBytes(UrlEncodeUnicode(str));
1430         }
1431 
1432 
1433         /// <devdoc>
1434         ///    <para>[To be supplied.]</para>
1435         /// </devdoc>
UrlDecode(string str)1436         public static string UrlDecode(string str) {
1437             if (str == null)
1438                 return null;
1439             return UrlDecode(str, Encoding.UTF8);
1440         }
1441 
1442 
1443         /// <devdoc>
1444         ///    <para>[To be supplied.]</para>
1445         /// </devdoc>
UrlDecode(string str, Encoding e)1446         public static string UrlDecode(string str, Encoding e) {
1447             return HttpEncoder.Current.UrlDecode(str, e);
1448         }
1449 
1450 
1451         /// <devdoc>
1452         ///    <para>[To be supplied.]</para>
1453         /// </devdoc>
UrlDecode(byte[] bytes, Encoding e)1454         public static string UrlDecode(byte[] bytes, Encoding e) {
1455             if (bytes == null)
1456                 return null;
1457             return UrlDecode(bytes, 0, bytes.Length, e);
1458         }
1459 
1460 
1461         /// <devdoc>
1462         ///    <para>[To be supplied.]</para>
1463         /// </devdoc>
UrlDecode(byte[] bytes, int offset, int count, Encoding e)1464         public static string UrlDecode(byte[] bytes, int offset, int count, Encoding e) {
1465             return HttpEncoder.Current.UrlDecode(bytes, offset, count, e);
1466         }
1467 
1468 
1469         /// <devdoc>
1470         ///    <para>[To be supplied.]</para>
1471         /// </devdoc>
UrlDecodeToBytes(string str)1472         public static byte[] UrlDecodeToBytes(string str) {
1473             if (str == null)
1474                 return null;
1475             return UrlDecodeToBytes(str, Encoding.UTF8);
1476         }
1477 
1478 
1479         /// <devdoc>
1480         ///    <para>[To be supplied.]</para>
1481         /// </devdoc>
UrlDecodeToBytes(string str, Encoding e)1482         public static byte[] UrlDecodeToBytes(string str, Encoding e) {
1483             if (str == null)
1484                 return null;
1485             return UrlDecodeToBytes(e.GetBytes(str));
1486         }
1487 
1488 
1489         /// <devdoc>
1490         ///    <para>[To be supplied.]</para>
1491         /// </devdoc>
UrlDecodeToBytes(byte[] bytes)1492         public static byte[] UrlDecodeToBytes(byte[] bytes) {
1493             if (bytes == null)
1494                 return null;
1495             return UrlDecodeToBytes(bytes, 0, (bytes != null) ? bytes.Length : 0);
1496         }
1497 
1498 
1499         /// <devdoc>
1500         ///    <para>[To be supplied.]</para>
1501         /// </devdoc>
UrlDecodeToBytes(byte[] bytes, int offset, int count)1502         public static byte[] UrlDecodeToBytes(byte[] bytes, int offset, int count) {
1503             return HttpEncoder.Current.UrlDecode(bytes, offset, count);
1504         }
1505 
1506 
1507         //////////////////////////////////////////////////////////////////////////
1508         //
1509         //  Misc helpers
1510         //
1511         //////////////////////////////////////////////////////////////////////////
1512 
FormatHttpDateTime(DateTime dt)1513         internal static String FormatHttpDateTime(DateTime dt) {
1514             if (dt < DateTime.MaxValue.AddDays(-1) && dt > DateTime.MinValue.AddDays(1))
1515                 dt = dt.ToUniversalTime();
1516             return dt.ToString("R", DateTimeFormatInfo.InvariantInfo);
1517         }
1518 
FormatHttpDateTimeUtc(DateTime dt)1519         internal static String FormatHttpDateTimeUtc(DateTime dt) {
1520             return dt.ToString("R", DateTimeFormatInfo.InvariantInfo);
1521         }
1522 
FormatHttpCookieDateTime(DateTime dt)1523         internal static String FormatHttpCookieDateTime(DateTime dt) {
1524             if (dt < DateTime.MaxValue.AddDays(-1) && dt > DateTime.MinValue.AddDays(1))
1525                 dt = dt.ToUniversalTime();
1526             return dt.ToString("ddd, dd-MMM-yyyy HH':'mm':'ss 'GMT'", DateTimeFormatInfo.InvariantInfo);
1527         }
1528 
1529         //
1530         // JavaScriptStringEncode
1531         //
1532 
JavaScriptStringEncode(string value)1533         public static String JavaScriptStringEncode(string value) {
1534             return JavaScriptStringEncode(value, false);
1535         }
1536 
JavaScriptStringEncode(string value, bool addDoubleQuotes)1537         public static String JavaScriptStringEncode(string value, bool addDoubleQuotes) {
1538             string encoded = HttpEncoder.Current.JavaScriptStringEncode(value);
1539             return (addDoubleQuotes) ? "\"" + encoded + "\"" : encoded;
1540         }
1541 
1542         /// <summary>
1543         /// Attempts to parse a co-ordinate as a double precision floating point value.
1544         /// This essentially does a Double.TryParse while disallowing specific floating point constructs such as the exponent.
1545         /// </summary>
TryParseCoordinates(string value, out double doubleValue)1546         internal static bool TryParseCoordinates(string value, out double doubleValue) {
1547             var flags = NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign;
1548             return Double.TryParse(value, flags, CultureInfo.InvariantCulture, out doubleValue);
1549         }
1550     }
1551 }
1552