httpserverutility.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / xsp / System / Web / httpserverutility.cs / 1 / httpserverutility.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 * Server intrinsic used to match ASP's object model 
 *
 * Copyright (c) 1999 Microsoft Corporation 
 */

// Don't entity encode high chars (160 to 256), to fix bugs VSWhidbey 85857/111927
// 
#define ENTITY_ENCODE_HIGH_ASCII_CHARS
 
namespace System.Web { 
    using System.Text;
    using System.Runtime.Serialization.Formatters; 
    using System.Threading;
    using System.Runtime.InteropServices;
    using System.IO;
    using System.Collections; 
    using System.Collections.Specialized;
    using System.Globalization; 
    using System.Web.Hosting; 
    using System.Web.Util;
    using System.Web.UI; 
    using System.Web.Configuration;
    using System.Security;
    using System.Security.Permissions;
    using System.Web.Management; 
    using System.Web.SessionState;
 
    internal abstract class ErrorFormatterGenerator { 
        internal abstract ErrorFormatter GetErrorFormatter(Exception e);
    } 


    /// 
    ///     
    ///       Provides several
    ///       helper methods that can be used in the processing of Web requests. 
    ///     
    /// 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public sealed class HttpServerUtility {
        private HttpContext _context;
        private HttpApplication _application;
 
        private static IDictionary _cultureCache = Hashtable.Synchronized(new Hashtable());
 
        internal HttpServerUtility(HttpContext context) { 
            _context = context;
        } 

        internal HttpServerUtility(HttpApplication application) {
            _application = application;
        } 

        // 
        // Misc ASP compatibility methods 
        //
 

        /// 
        ///    
        ///       Instantiates a COM object identified via a progid. 
        ///    
        ///  
        [SecurityPermission(SecurityAction.Demand, Unrestricted = true)] 
        public object CreateObject(string progID) {
            Type type = null; 
            object obj = null;

            try {
#if !FEATURE_PAL // FEATURE_PAL does not enable COM 
                type = Type.GetTypeFromProgID(progID);
#else // !FEATURE_PAL 
                throw new NotImplementedException("ROTORTODO"); 
#endif // !FEATURE_PAL
            } 
            catch {
            }

            if (type == null) { 
                throw new HttpException(SR.GetString(SR.Could_not_create_object_of_type, progID));
            } 
 
            // Disallow Apartment components in non-compat mode
            AspCompatApplicationStep.CheckThreadingModel(progID, type.GUID); 

            // Instantiate the object
            obj = Activator.CreateInstance(type);
 
            // For ASP compat: take care of OnPageStart/OnPageEnd
            AspCompatApplicationStep.OnPageStart(obj); 
 
            return obj;
        } 


        /// 
        ///     
        ///       Instantiates a COM object identified via a Type.
        ///     
        ///  
        [SecurityPermission(SecurityAction.Demand, UnmanagedCode=true)]
        public object CreateObject(Type type) { 
            // Disallow Apartment components in non-compat mode
            AspCompatApplicationStep.CheckThreadingModel(type.FullName, type.GUID);

            // Instantiate the object 
            Object obj = Activator.CreateInstance(type);
 
            // For ASP compat: take care of OnPageStart/OnPageEnd 
            AspCompatApplicationStep.OnPageStart(obj);
 
            return obj;
        }

 

        ///  
        ///     
        ///       Instantiates a COM object identified via a clsid.
        ///     
        /// 
        [SecurityPermission(SecurityAction.Demand, UnmanagedCode=true)]
        public object CreateObjectFromClsid(string clsid) {
            Type type = null; 
            object obj = null;
 
            // Create a Guid out of it 
            Guid guid = new Guid(clsid);
 
            // Disallow Apartment components in non-compat mode
            AspCompatApplicationStep.CheckThreadingModel(clsid, guid);

            try { 
#if !FEATURE_PAL // FEATURE_PAL does not enable COM
                type = Type.GetTypeFromCLSID(guid, null, true /*throwOnError*/); 
#else // !FEATURE_PAL 
                throw new NotImplementedException("ROTORTODO");
#endif // !FEATURE_PAL 

                // Instantiate the object
                obj = Activator.CreateInstance(type);
            } 
            catch {
            } 
 
            if (obj == null) {
                throw new HttpException( 
                    SR.GetString(SR.Could_not_create_object_from_clsid, clsid));
            }

            // For ASP compat: take care of OnPageStart/OnPageEnd 
            AspCompatApplicationStep.OnPageStart(obj);
 
            return obj; 
        }
 
        // Internal static method that returns a read-only, non-user override accounted, CultureInfo object
        internal static CultureInfo CreateReadOnlyCultureInfo(string name) {
            if (!_cultureCache.Contains(name)) {
                // To be threadsafe, get the lock before creating 
                lock (_cultureCache) {
                    if (_cultureCache[name] == null) { 
                        _cultureCache[name] = CultureInfo.ReadOnly(new CultureInfo(name)); 
                    }
                } 
            }
            return (CultureInfo)_cultureCache[name];
        }
 
        // Internal static method that returns a read-only, non-user override accounted, culture specific CultureInfo object
        internal static CultureInfo CreateReadOnlySpecificCultureInfo(string name) { 
            if(name.IndexOf('-') > 0) { 
                return CreateReadOnlyCultureInfo(name);
            } 
            CultureInfo ci = CultureInfo.CreateSpecificCulture(name);
            if (!_cultureCache.Contains(ci.Name)) {
                //To be threadsafe, get the lock before creating
                lock (_cultureCache) { 
                    if (_cultureCache[ci.Name] == null) {
                        _cultureCache[ci.Name] = CultureInfo.ReadOnly(ci); 
                    } 
                }
            } 
            return (CultureInfo)_cultureCache[ci.Name];
        }

        // Internal static method that returns a read-only, non-user override accounted, CultureInfo object 
        internal static CultureInfo CreateReadOnlyCultureInfo(int culture) {
            if (!_cultureCache.Contains(culture)) { 
                // To be threadsafe, get the lock before creating 
                lock (_cultureCache) {
                    if (_cultureCache[culture] == null) { 
                        _cultureCache[culture] = CultureInfo.ReadOnly(new CultureInfo(culture));
                    }
                }
            } 
            return (CultureInfo)_cultureCache[culture];
        } 
 
        /// 
        ///     
        ///       Maps a virtual path to a physical path.
        ///    
        /// 
        public string MapPath(string path) { 
            if (_context == null)
                throw new HttpException(SR.GetString(SR.Server_not_available)); 
            // Disable hiding the request so that Server.MapPath works when called from 
            // Application_Start in integrated mode
            bool unhideRequest = _context.HideRequestResponse; 
            string realPath;
            try {
                if (unhideRequest) {
                    _context.HideRequestResponse = false; 
                }
                realPath = _context.Request.MapPath(path); 
            } 
            finally {
                if (unhideRequest) { 
                    _context.HideRequestResponse = true;
                }
            }
            return realPath; 
        }
 
 
        /// 
        ///    Returns the last recorded exception. 
        /// 
        public Exception GetLastError() {
            if (_context != null)
                return _context.Error; 
            else if (_application != null)
                return _application.LastError; 
            else 
                return null;
        } 


        /// 
        ///    Clears the last error. 
        /// 
        public void ClearError() { 
            if (_context != null) 
                _context.ClearError();
            else if (_application != null) 
                _application.ClearError();
        }

        // 
        // Server.Transfer/Server.Execute -- child requests
        // 
 

        ///  
        ///    
        ///       Executes a new request (using the specified URL path as the target). Unlike
        ///       the Transfer method, execution of the original page continues after the executed
        ///       page completes. 
        ///    
        ///  
        public void Execute(string path) { 
            Execute(path, null, true /*preserveForm*/);
        } 


        /// 
        ///     
        ///       Executes a new request (using the specified URL path as the target). Unlike
        ///       the Transfer method, execution of the original page continues after the executed 
        ///       page completes. 
        ///    
        ///  
        public void Execute(string path, TextWriter writer) {
            Execute(path, writer, true /*preserveForm*/);
        }
 

        ///  
        ///     
        ///       Executes a new request (using the specified URL path as the target). Unlike
        ///       the Transfer method, execution of the original page continues after the executed 
        ///       page completes.
        ///       If preserveForm is false, the QueryString and Form collections are cleared.
        ///    
        ///  
        public void Execute(string path, bool preserveForm) {
            Execute(path, null, preserveForm); 
        } 

 
        /// 
        ///    
        ///       Executes a new request (using the specified URL path as the target). Unlike
        ///       the Transfer method, execution of the original page continues after the executed 
        ///       page completes.
        ///       If preserveForm is false, the QueryString and Form collections are cleared. 
        ///     
        /// 
        public void Execute(string path, TextWriter writer, bool preserveForm) { 
            if (_context == null)
                throw new HttpException(SR.GetString(SR.Server_not_available));

            if (path == null) 
                throw new ArgumentNullException("path");
 
            string queryStringOverride = null; 
            HttpRequest request = _context.Request;
            HttpResponse response = _context.Response; 

            // Remove potential cookie-less session id (ASURT 100558)
            path = response.RemoveAppPathModifier(path);
 
            // Allow query string override
            int iqs = path.IndexOf('?'); 
            if (iqs >= 0) { 
                queryStringOverride = path.Substring(iqs+1);
                path = path.Substring(0, iqs); 
            }

            if (!UrlPath.IsValidVirtualPathWithoutProtocol(path))
                throw new ArgumentException(SR.GetString(SR.Invalid_path_for_child_request, path)); 

            VirtualPath virtualPath = VirtualPath.Create(path); 
 
            // Find the handler for the path
 
            IHttpHandler handler = null;

            string physPath = request.MapPath(virtualPath);        // get physical path
            VirtualPath filePath = request.FilePathObject.Combine(virtualPath);    // vpath 

            // Demand read access to the physical path of the target handler 
            InternalSecurityPermissions.FileReadAccess(physPath).Demand(); 

            // We need to Assert since there typically is user code on the stack (VSWhidbey 270965) 
            InternalSecurityPermissions.Unrestricted.Assert();

            try {
                // paths that ends with . are disallowed as they are used to get around 
                // extension mappings and server source as static file
                if (StringUtil.StringEndsWith(virtualPath.VirtualPathString, '.')) 
                    throw new HttpException(404, String.Empty); 

                bool useAppConfig = !filePath.IsWithinAppRoot; 

                using (new HttpContextWrapper(_context)) {

                    try { 
                        // We need to increase the depth when calling MapHttpHandler,
                        // since PageHandlerFactory relies on it 
                        _context.ServerExecuteDepth++; 

                        if (_context.WorkerRequest is IIS7WorkerRequest) { 
                            handler = _context.ApplicationInstance.MapIntegratedHttpHandler(
                                _context,
                                request.RequestType,
                                filePath, 
                                physPath,
                                useAppConfig, 
                                true /*convertNativeStaticFileModule*/); 
                        }
                        else { 
                            handler = _context.ApplicationInstance.MapHttpHandler(
                                _context,
                                request.RequestType,
                                filePath, 
                                physPath,
                                useAppConfig); 
                        } 
                    }
                    finally { 
                        _context.ServerExecuteDepth--;
                    }
                }
            } 
            catch (Exception e) {
                // 500 errors (compilation errors) get preserved 
                if (e is HttpException) { 
                    int code = ((HttpException)e).GetHttpCode();
 
                    if (code != 500 && code != 404) {
                        e = null;
                    }
                } 

                throw new HttpException(SR.GetString(SR.Error_executing_child_request_for_path, path), e); 
            } 

            ExecuteInternal(handler, writer, preserveForm, true /*setPreviousPage*/, 
                virtualPath, filePath, physPath, null, queryStringOverride);
        }

 
        public void Execute(IHttpHandler handler, TextWriter writer, bool preserveForm) {
            if (_context == null) 
                throw new HttpException(SR.GetString(SR.Server_not_available)); 

            Execute(handler, writer, preserveForm, true /*setPreviousPage*/); 
        }

        internal void Execute(IHttpHandler handler, TextWriter writer, bool preserveForm, bool setPreviousPage) {
            HttpRequest request = _context.Request; 
            VirtualPath filePath = request.CurrentExecutionFilePathObject;
            string physicalPath = request.MapPath(filePath); 
 
            ExecuteInternal(handler, writer, preserveForm, setPreviousPage,
                null, filePath, physicalPath, null, null); 
        }

        private void ExecuteInternal(IHttpHandler handler, TextWriter writer, bool preserveForm, bool setPreviousPage,
            VirtualPath path, VirtualPath filePath, string physPath, Exception error, string queryStringOverride) { 

            if (handler == null) 
                throw new ArgumentNullException("handler"); 

            HttpRequest request = _context.Request; 
            HttpResponse response = _context.Response;
            HttpApplication app = _context.ApplicationInstance;

            HttpValueCollection savedForm = null; 
            VirtualPath savedCurrentExecutionFilePath = null;
            string savedQueryString = null; 
            TextWriter savedOutputWriter = null; 
            AspNetSynchronizationContext savedSyncContext = null;
 
            // Transaction wouldn't flow into ASPCOMPAT mode -- need to report an error
            VerifyTransactionFlow(handler);

            // create new trace context 
            _context.PushTraceContext();
 
            // set the new handler as the current handler 
            _context.SetCurrentHandler(handler);
 
            // because we call this synchrnously async operations must be disabled
            bool originalSyncContextWasEnabled = _context.SyncContext.Enabled;
            _context.SyncContext.Disable();
 
            // Execute the handler
            try { 
                try { 
                    _context.ServerExecuteDepth++;
 
                    savedCurrentExecutionFilePath = request.SwitchCurrentExecutionFilePath(filePath);

                    if (!preserveForm) {
                        savedForm = request.SwitchForm(new HttpValueCollection()); 

                        // Clear out the query string, but honor overrides 
                        if (queryStringOverride == null) 
                            queryStringOverride = String.Empty;
                    } 

                    // override query string if requested
                    if (queryStringOverride != null) {
                        savedQueryString = request.QueryStringText; 
                        request.QueryStringText = queryStringOverride;
                    } 
 
                    // capture output if requested
                    if (writer != null) 
                        savedOutputWriter = response.SwitchWriter(writer);

                    Page targetPage = handler as Page;
                    if (targetPage != null) { 
                        if (setPreviousPage) {
                            // Set the previousPage of the new Page as the previous Page 
                            targetPage.SetPreviousPage(_context.PreviousHandler as Page); 
                        }
 
                        Page sourcePage = _context.Handler as Page;

#pragma warning disable 0618    // To avoid deprecation warning
                        // If the source page of the transfer has smart nav on, 
                        // always do as if the destination has it too (ASURT 97732)
                        if (sourcePage != null && sourcePage.SmartNavigation) 
                            targetPage.SmartNavigation = true; 
#pragma warning restore 0618
 
                        // If the target page is async need to save/restore [....] context
                        if (targetPage is IHttpAsyncHandler) {
                            savedSyncContext = _context.InstallNewAspNetSynchronizationContext();
                        } 
                    }
 
                    if ((handler is StaticFileHandler || handler is DefaultHttpHandler) && 
                       !DefaultHttpHandler.IsClassicAspRequest(filePath.VirtualPathString)) {
                        // cannot apply static files handler directly 
                        // -- it would dump the source of the current page
                        // instead just dump the file content into response
                        try {
                            response.WriteFile(physPath); 
                        }
                        catch { 
                            // hide the real error as it could be misleading 
                            // in case of mismapped requests like /foo.asmx/bar
                            error = new HttpException(404, String.Empty); 
                        }
                    }
                    else if (!(handler is Page)) {
                        // disallow anything but pages 
                        error = new HttpException(404, String.Empty);
                    } 
                    else if (handler is IHttpAsyncHandler) { 
                        // Asynchronous handler
 
                        // suspend cancellable period (don't abort this thread while
                        // we wait for another to finish)
                        bool isCancellable =  _context.IsInCancellablePeriod;
                        if (isCancellable) 
                            _context.EndCancellablePeriod();
 
                        try { 
                            IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler)handler;
 
                            IAsyncResult ar = asyncHandler.BeginProcessRequest(_context, null, null);

                            // wait for completion
                            if (!ar.IsCompleted) { 
                                // suspend app lock while waiting
                                bool needToRelock = false; 
 
                                try {
                                    try {} finally { 
                                        Monitor.Exit(app);
                                        needToRelock = true;
                                    }
 
                                    WaitHandle h = ar.AsyncWaitHandle;
 
                                    if (h != null) { 
                                        h.WaitOne();
                                    } 
                                    else {
                                        while (!ar.IsCompleted)
                                            Thread.Sleep(1);
                                    } 
                                }
                                finally { 
                                    if (needToRelock) { 
                                        Monitor.Enter(app);
                                    } 
                                }
                            }

                            // end the async operation (get error if any) 

                            try { 
                                asyncHandler.EndProcessRequest(ar); 
                            }
                            catch (Exception e) { 
                                error = e;
                            }
                        }
                        finally { 
                            // resume cancelleable period
                            if (isCancellable) 
                                _context.BeginCancellablePeriod(); 
                        }
                    } 
                    else {
                        // Synchronous handler

                        using (new HttpContextWrapper(_context)) { 
                            try {
                                handler.ProcessRequest(_context); 
                            } 
                            catch (Exception e) {
                                error = e; 
                            }
                        }
                    }
                } 
                finally {
                    _context.ServerExecuteDepth--; 
 
                    // Restore the handlers;
                    _context.RestoreCurrentHandler(); 

                    // restore output writer
                    if (savedOutputWriter != null)
                        response.SwitchWriter(savedOutputWriter); 

                    // restore overriden query string 
                    if (queryStringOverride != null && savedQueryString != null) 
                        request.QueryStringText = savedQueryString;
 
                    if (savedForm != null)
                        request.SwitchForm(savedForm);

                    request.SwitchCurrentExecutionFilePath(savedCurrentExecutionFilePath); 

                    if (savedSyncContext != null) { 
                        _context.RestoreSavedAspNetSynchronizationContext(savedSyncContext); 
                    }
 
                    if (originalSyncContextWasEnabled) {
                        _context.SyncContext.Enable();
                    }
 
                    // restore trace context
                    _context.PopTraceContext(); 
                } 
            }
            catch { // Protect against exception filters 
                throw;
            }

            // Report any error 
            if (error != null) {
                // suppress errors with HTTP codes (for child requests they mislead more than help) 
                if (error is HttpException && ((HttpException)error).GetHttpCode() != 500) 
                    error = null;
 
                if (path != null)
                    throw new HttpException(SR.GetString(SR.Error_executing_child_request_for_path, path), error);

                throw new HttpException(SR.GetString(SR.Error_executing_child_request_for_handler, handler.GetType().ToString()), error); 
            }
        } 
 

        ///  
        ///    
        ///       Terminates execution of the current page and begins execution of a new
        ///       request using the supplied URL path.
        ///       If preserveForm is false, the QueryString and Form collections are cleared. 
        ///    
        ///  
        public void Transfer(string path, bool preserveForm) { 
            Page page = _context.Handler as Page;
            if ((page != null) && page.IsCallback) { 
                throw new ApplicationException(SR.GetString(SR.Transfer_not_allowed_in_callback));
            }

            // execute child request 

            Execute(path, null, preserveForm); 
 
            // suppress the remainder of the current one
 
            _context.Response.End();
        }

 
        /// 
        ///     
        ///       Terminates execution of the current page and begins execution of a new 
        ///       request using the supplied URL path.
        ///     
        /// 
        public void Transfer(string path) {
            // Make sure the transfer is not treated as a postback, which could cause a stack
            // overflow if the user doesn't expect it (VSWhidbey 181013). 
            // If the use *does* want it treated as a postback, they can call Transfer(path, true).
            bool savedPreventPostback = _context.PreventPostback; 
            _context.PreventPostback = true; 

            Transfer(path, true /*preserveForm*/); 

            _context.PreventPostback = savedPreventPostback;
        }
 

        public void Transfer(IHttpHandler handler, bool preserveForm) { 
            Page page = handler as Page; 
            if ((page != null) && page.IsCallback) {
                throw new ApplicationException(SR.GetString(SR.Transfer_not_allowed_in_callback)); 
            }

            Execute(handler, null, preserveForm);
 
            // suppress the remainder of the current one
 
            _context.Response.End(); 
        }
 
        public void TransferRequest(string path)
        {
            TransferRequest(path, false, null, null);
        } 

        public void TransferRequest(string path, bool preserveForm) 
        { 
            TransferRequest(path, preserveForm, null, null);
        } 

        public void TransferRequest(string path, bool preserveForm, string method, NameValueCollection headers) {
            if (!HttpRuntime.UseIntegratedPipeline) {
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
            }
 
            if (_context == null) { 
                throw new HttpException(SR.GetString(SR.Server_not_available));
            } 

            if (path == null) {
                throw new ArgumentNullException("path");
            } 

            IIS7WorkerRequest wr = _context.WorkerRequest as IIS7WorkerRequest; 
            HttpRequest request = _context.Request; 
            HttpResponse response = _context.Response;
 
            if (wr == null) {
                throw new HttpException(SR.GetString(SR.Server_not_available));
            }
 
            // Remove potential cookie-less session id (ASURT 100558)
            path = response.RemoveAppPathModifier(path); 
 
            // Extract query string if specified
            String qs = null; 
            int iqs = path.IndexOf('?');
            if (iqs >= 0) {
                qs = (iqs < path.Length-1) ? path.Substring(iqs+1) : String.Empty;
                path = path.Substring(0, iqs); 
            }
 
            if (!UrlPath.IsValidVirtualPathWithoutProtocol(path)) { 
                throw new ArgumentException(SR.GetString(SR.Invalid_path_for_child_request, path));
            } 

            VirtualPath virtualPath = request.FilePathObject.Combine(VirtualPath.Create(path));
            string physPath = request.MapPath(path);
 
            // Demand read access to the physical path of the target handler
            InternalSecurityPermissions.FileReadAccess(physPath).Demand(); 
 
            //  Schedule the child execution
            wr.ScheduleExecuteUrl( virtualPath.VirtualPathString, 
                                   qs,
                                   method,
                                   preserveForm,
                                   preserveForm ? request.EntityBody : null, 
                                   headers);
 
            // force the completion of the current request so that the 
            // child execution can be performed immediately after unwind
            _context.ApplicationInstance.EnsureReleaseState(); 

            // DevDiv Bugs 162750: IIS7 Integrated Mode:  TransferRequest performance issue
            // Instead of calling Response.End we call HttpApplication.CompleteRequest()
            _context.ApplicationInstance.CompleteRequest(); 
        }
 
        private void VerifyTransactionFlow(IHttpHandler handler) { 
            Page topPage = _context.Handler as Page;
            Page childPage = handler as Page; 

            if (childPage != null && childPage.IsInAspCompatMode && // child page aspcompat
                topPage != null && !topPage.IsInAspCompatMode &&    // top page is not aspcompat
                Transactions.Utils.IsInTransaction) {               // we are in transaction 

                throw new HttpException(SR.GetString(SR.Transacted_page_calls_aspcompat)); 
            } 
        }
 
        //
        // Static method to execute a request outside of HttpContext and capture the response
        //
 
        internal static void ExecuteLocalRequestAndCaptureResponse(String path, TextWriter writer,
                                                                ErrorFormatterGenerator errorFormatterGenerator) { 
            HttpRequest request = new HttpRequest( 
                                          VirtualPath.CreateAbsolute(path),
                                          String.Empty); 

            HttpResponse response = new HttpResponse(writer);

            HttpContext context = new HttpContext(request, response); 

            HttpApplication app = HttpApplicationFactory.GetApplicationInstance(context) as HttpApplication; 
            context.ApplicationInstance = app; 

            try { 
                context.Server.Execute(path);
            }
            catch (HttpException e) {
                if (errorFormatterGenerator != null) { 
                    context.Response.SetOverrideErrorFormatter(errorFormatterGenerator.GetErrorFormatter(e));
                } 
 
                context.Response.ReportRuntimeError(e, false, true);
            } 
            finally {
                if (app != null) {
                    context.ApplicationInstance = null;
                    HttpApplicationFactory.RecycleApplicationInstance(app); 
                }
            } 
        } 

        // 
        // Computer name
        //

        private static object _machineNameLock = new object(); 
        private static string _machineName;
        private const int _maxMachineNameLength = 256; 
 

        ///  
        ///    
        ///       Gets
        ///       the server machine name.
        ///     
        /// 
        public string MachineName { 
            [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)] 
            get {
                return GetMachineNameInternal(); 
            }
        }

        internal static string GetMachineNameInternal() 
        {
            if (_machineName != null) 
                return _machineName; 
            lock (_machineNameLock)
            { 
                if (_machineName != null)
                    return _machineName;

                StringBuilder   buf = new StringBuilder (_maxMachineNameLength); 
                int             len = _maxMachineNameLength;
 
                if (UnsafeNativeMethods.GetComputerName (buf, ref len) == 0) 
                    throw new HttpException (SR.GetString (SR.Get_computer_name_failed));
 
                _machineName = buf.ToString();
            }
            return _machineName;
        } 

        // 
        // Request Timeout 
        //
 

        /// 
        ///    
        ///       Request timeout in seconds 
        ///    
        ///  
        public int ScriptTimeout { 
            get {
                if (_context != null) { 
                    return Convert.ToInt32(_context.Timeout.TotalSeconds, CultureInfo.InvariantCulture);
                }
                else {
                    return HttpRuntimeSection.DefaultExecutionTimeout; 
                }
            } 
 
            [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)]
            set { 
                if (_context == null)
                    throw new HttpException(SR.GetString(SR.Server_not_available));
                if (value <= 0)
                    throw new ArgumentOutOfRangeException("value"); 
                _context.Timeout = new TimeSpan(0, 0, value);
            } 
        } 

        // 
        // Encoding / Decoding -- wrappers for HttpUtility
        //

 
        /// 
        ///     
        ///       HTML 
        ///       decodes a given string and
        ///       returns the decoded string. 
        ///    
        /// 
        public string HtmlDecode(string s) {
            return HttpUtility.HtmlDecode(s); 
        }
 
 
        /// 
        ///     
        ///       HTML
        ///       decode a string and send the result to a TextWriter output
        ///       stream.
        ///     
        /// 
        public void HtmlDecode(string s, TextWriter output) { 
            HttpUtility.HtmlDecode(s, output); 
        }
 

        /// 
        ///    
        ///       HTML 
        ///       encodes a given string and
        ///       returns the encoded string. 
        ///     
        /// 
        public string HtmlEncode(string s) { 
            return HttpUtility.HtmlEncode(s);
        }

 
        /// 
        ///     
        ///       HTML 
        ///       encodes
        ///       a string and returns the output to a TextWriter stream of output. 
        ///    
        /// 
        public void HtmlEncode(string s, TextWriter output) {
            HttpUtility.HtmlEncode(s, output); 
        }
 
 
        /// 
        ///     
        ///       URL
        ///       encodes a given
        ///       string and returns the encoded string.
        ///     
        /// 
        public string UrlEncode(string s) { 
            Encoding e = (_context != null) ? _context.Response.ContentEncoding : Encoding.UTF8; 
            return HttpUtility.UrlEncode(s, e);
        } 


        /// 
        ///     
        ///       URL encodes a path portion of a URL string and returns the encoded string.
        ///     
        ///  
        public string UrlPathEncode(string s) {
            return HttpUtility.UrlPathEncode(s); 
        }


        ///  
        ///    
        ///       URL 
        ///       encodes 
        ///       a string and returns the output to a TextWriter output stream.
        ///     
        /// 
        public void UrlEncode(string s, TextWriter output) {
            if (s != null)
                output.Write(UrlEncode(s)); 
        }
 
 
        /// 
        ///     
        ///       URL decodes a string and returns the output in a string.
        ///    
        /// 
        public string UrlDecode(string s) { 
            Encoding e = (_context != null) ? _context.Request.ContentEncoding : Encoding.UTF8;
            return HttpUtility.UrlDecode(s, e); 
        } 

 
        /// 
        ///    
        ///       URL decodes a string and returns the output as a TextWriter output
        ///       stream. 
        ///    
        ///  
        public void UrlDecode(string s, TextWriter output) { 
            if (s != null)
                output.Write(UrlDecode(s)); 
        }

        /////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////
 
        static public string UrlTokenEncode(byte [] input) 
        {
            if (input == null) 
                throw new ArgumentNullException("input");
            if (input.Length < 1)
                return String.Empty;
 
            string  base64Str   = null;
            int     endPos      = 0; 
            char[]  base64Chars = null; 

            //////////////////////////////////////////////////////// 
            // Step 1: Do a Base64 encoding
            base64Str = Convert.ToBase64String(input);
            if (base64Str == null)
                return null; 

            //////////////////////////////////////////////////////// 
            // Step 2: Find how many padding chars are present in the end 
            for (endPos = base64Str.Length; endPos > 0; endPos--)
            { 
                if (base64Str[endPos - 1] != '=') // Found a non-padding char!
                {
                    break; // Stop here
                } 
            }
 
            //////////////////////////////////////////////////////// 
            // Step 3: Create char array to store all non-padding chars,
            //      plus a char to indicate how many padding chars are needed 
            base64Chars = new char[endPos + 1];
            base64Chars[endPos] = (char)((int)'0' + base64Str.Length - endPos); // Store a char at the end, to indicate how many padding chars are needed

            //////////////////////////////////////////////////////// 
            // Step 3: Copy in the other chars. Transform the "+" to "-", and "/" to "_"
            for (int iter = 0; iter < endPos; iter++) 
            { 
                char c = base64Str[iter];
 
                switch (c)
                {
                    case '+':
                        base64Chars[iter] = '-'; 
                        break;
 
                    case '/': 
                        base64Chars[iter] = '_';
                        break; 

                    case '=':
                        Debug.Assert (false);
                        base64Chars[iter] = c; 
                        break;
 
                    default: 
                        base64Chars[iter] = c;
                        break; 
                }
            }
            return new string(base64Chars);
        } 

        ///////////////////////////////////////////////////////////////////////////// 
        ///////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////
 
        static public byte [] UrlTokenDecode(string input) {
            if (input == null)
                throw new ArgumentNullException("input");
 
            int len = input.Length;
            if (len < 1) 
                return new byte[0]; 

            /////////////////////////////////////////////////////////////////// 
            // Step 1: Calculate the number of padding chars to append to this string.
            //         The number of padding chars to append is stored in the last char of the string.
            int numPadChars = (int)input[len - 1] - (int)'0';
            if (numPadChars < 0 || numPadChars > 10) 
                return null;
 
 
            ///////////////////////////////////////////////////////////////////
            // Step 2: Create array to store the chars (not including the last char) 
            //          and the padding chars
            char[] base64Chars = new char[len - 1 + numPadChars];

 
            ////////////////////////////////////////////////////////
            // Step 3: Copy in the chars. Transform the "-" to "+", and "*" to "/" 
            for (int iter = 0; iter < len - 1; iter++) 
            {
                char c = input[iter]; 

                switch (c)
                {
                    case '-': 
                        base64Chars[iter] = '+';
                        break; 
 
                    case '_':
                        base64Chars[iter] = '/'; 
                        break;

                    default:
                        base64Chars[iter] = c; 
                        break;
                } 
            } 

            //////////////////////////////////////////////////////// 
            // Step 4: Add padding chars
            for (int iter = len - 1; iter < base64Chars.Length; iter++)
            {
                base64Chars[iter] = '='; 
            }
 
            // Do the actual conversion 
            return Convert.FromBase64CharArray (base64Chars, 0, base64Chars.Length);
        } 
    }


    ///  
    /// 
 
    // VSWhidbey 473228 - removed link demand from HttpUtility for ClickOnce scenario 
    public sealed class HttpUtility {
 
        public HttpUtility () {}
 		
		//////////////////////////////////////////////////////////////////////////
        // 
        //  HTML Encoding / Decoding
        // 
 

        ///  
        ///    
        ///       HTML decodes a string and returns the decoded string.
        ///    
        ///  
        public static string HtmlDecode(string s) {
            if (s == null) 
                return null; 

            // See if this string needs to be decoded at all.  If no 
            // ampersands are found, then no special HTML-encoded chars
            // are in the string.
            if (s.IndexOf('&') < 0)
                return s; 

            StringBuilder builder = new StringBuilder(); 
            StringWriter writer = new StringWriter(builder); 

            HtmlDecode(s, writer); 

            return builder.ToString();
        }
 

        ///  
        ///     
        ///       HTML decode a string and send the result to a TextWriter output stream.
        ///     
        /// 
        private static char[] s_entityEndingChars = new char[] {';', '&'};
        public static void HtmlDecode(string s, TextWriter output) {
            if (s == null) 
                return;
 
            if (s.IndexOf('&') < 0) { 
                output.Write(s);        // good as is
                return; 
            }

            int l = s.Length;
            for (int i = 0; i < l; i++) { 
                char ch = s[i];
 
                if (ch == '&') { 
                    // We found a '&'. Now look for the next ';' or '&'. The idea is that
                    // if we find another '&' before finding a ';', then this is not an entity, 
                    // and the next '&' might start a real entity (VSWhidbey 275184)
                    int index = s.IndexOfAny(s_entityEndingChars, i + 1);
                    if (index > 0 && s[index] == ';') {
                        string entity = s.Substring(i + 1, index - i - 1); 

                        if (entity.Length > 1 && entity[0] == '#') { 
                            try { 
                                // The # syntax can be in decimal or hex, e.g.
                                //      å  --> decimal 
                                //      å  --> same char in hex
                                // See http://www.w3.org/TR/REC-html40/charset.html#entities
                                if (entity[1] == 'x' || entity[1] == 'X')
                                    ch = (char) Int32.Parse(entity.Substring(2), NumberStyles.AllowHexSpecifier); 
                                else
                                    ch = (char) Int32.Parse(entity.Substring(1)); 
                                i = index; // already looked at everything until semicolon 
                            }
                            catch (System.FormatException) { 
                                i++;    //if the number isn't valid, ignore it
                            }
                            catch (System.ArgumentException) {
                                i++;    // if there is no number, ignore it. 
                            }
                        } 
                        else { 
                            i = index; // already looked at everything until semicolon
 
                            char entityChar = HtmlEntities.Lookup(entity);
                            if (entityChar != (char)0) {
                                ch = entityChar;
                            } 
                            else {
                                output.Write('&'); 
                                output.Write(entity); 
                                output.Write(';');
                                continue; 
                            }
                        }

                    } 
                }
 
                output.Write(ch); 
            }
        } 


        /// 
        ///     
        ///       HTML encodes a string and returns the encoded string.
        ///     
        ///  
        public static String HtmlEncode(String s) {
            if (s == null) 
                return null;

            int pos = IndexOfHtmlEncodingChars(s, 0);
            if (pos == -1) 
                return s;
 
            StringBuilder builder = new StringBuilder(s.Length + 5); 
            int cch = s.Length;
            int startPos = 0; 
            for (;;) {
                if (pos > startPos) {
                    builder.Append(s, startPos, pos - startPos);
                } 

                char ch = s[pos]; 
                if (ch <= '>') { 
                    switch (ch) {
                        case '<': 
                            builder.Append("<");
                            break;
                        case '>':
                            builder.Append(">"); 
                            break;
                        case '"': 
                            builder.Append("""); 
                            break;
                        case '&': 
                            builder.Append("&");
                            break;
                        default:
                            Debug.Assert(false, "Unexpected value for ch, ch=" + ch); 
                            break;
                    } 
                } 
                else {
#if ENTITY_ENCODE_HIGH_ASCII_CHARS 
                    Debug.Assert(ch >= 160 && ch < 256, "ch >= 160 && ch < 256");

                    // The seemingly arbitrary 160 comes from RFC
                    builder.Append("&#"); 
                    builder.Append(((int)ch).ToString(NumberFormatInfo.InvariantInfo));
                    builder.Append(';'); 
#else 
                    Debug.Assert(false);
#endif // ENTITY_ENCODE_HIGH_ASCII_CHARS 
                }

                startPos = pos + 1;
                if (startPos >= cch) 
                    break;
 
                pos = IndexOfHtmlEncodingChars(s, startPos); 
                if (pos == -1) {
                    builder.Append(s, startPos, cch - startPos); 
                    break;
                }
            }
 
            return builder.ToString();
        } 
 

        ///  
        ///    
        ///       HTML encodes a string and returns the output to a TextWriter stream of
        ///       output.
        ///     
        /// 
        public unsafe static void HtmlEncode(String s, TextWriter output) { 
            if (s == null) 
                return;
 
            int index = IndexOfHtmlEncodingChars(s, 0);
            if (index == -1) {
                output.Write(s);
                return; 
            }
 
            Debug.Assert(0 <= index && index <= s.Length, "0 <= index && index <= s.Length"); 

            int cch = s.Length - index; 
            fixed (char * str = s) {
                char *pch = str;
                while (index-- > 0) {
                    output.Write(*pch++); 
                }
 
                while (cch-- > 0) { 
                    char ch = *pch++;
                    if (ch <= '>') { 
                        switch (ch) {
                            case '<':
                                output.Write("<");
                                break; 
                            case '>':
                                output.Write(">"); 
                                break; 
                            case '"':
                                output.Write("""); 
                                break;
                            case '&':
                                output.Write("&");
                                break; 
                            default:
                                output.Write(ch); 
                                break; 
                        }
                    } 
#if ENTITY_ENCODE_HIGH_ASCII_CHARS
                    else if (ch >= 160 && ch < 256) {
                        // The seemingly arbitrary 160 comes from RFC
                        output.Write("&#"); 
                        output.Write(((int)ch).ToString(NumberFormatInfo.InvariantInfo));
                        output.Write(';'); 
                    } 
#endif // ENTITY_ENCODE_HIGH_ASCII_CHARS
                    else { 
                        output.Write(ch);
                    }
                }
            } 
        }
 
        static unsafe int IndexOfHtmlEncodingChars(string s, int startPos) { 
            Debug.Assert(0 <= startPos && startPos <= s.Length, "0 <= startPos && startPos <= s.Length");
 
            int cch = s.Length - startPos;
            fixed (char * str = s) {
                for (char *pch = &str[startPos]; cch > 0; pch++, cch--) {
                    char ch = *pch; 
                    if (ch <= '>') {
                        switch (ch) { 
                            case '<': 
                            case '>':
                            case '"': 
                            case '&':
                                return s.Length - cch;
                        }
                    } 
#if ENTITY_ENCODE_HIGH_ASCII_CHARS
                    else if (ch >= 160 && ch < 256) { 
                        return s.Length - cch; 
                    }
#endif // ENTITY_ENCODE_HIGH_ASCII_CHARS 
                }
            }

            return -1; 
        }
 
 
        /// 
        ///     
        ///       Encodes a string to make it a valid HTML attribute and returns the encoded string.
        ///    
        /// 
        public static String HtmlAttributeEncode(String s) { 
            if (s == null)
                return null; 
 
            int pos = IndexOfHtmlAttributeEncodingChars(s, 0);
            if (pos == -1) 
                return s;

            StringBuilder builder = new StringBuilder(s.Length + 5);
            int cch = s.Length; 
            int startPos = 0;
            for (;;) { 
                if (pos > startPos) { 
                    builder.Append(s, startPos, pos - startPos);
                } 

                char ch = s[pos];
                switch (ch) {
                    case '"': 
                        builder.Append(""");
                        break; 
                    case '&': 
                        builder.Append("&");
                        break; 
                    case '<':
                        // Whidbey 32404: The character '<' is not valid in an XML attribute value.
                        // (See the W3C XML rec).
                        builder.Append("<"); 
                        break;
 
                    default: 
                        Debug.Assert(false, "Unexpected value for ch, ch=" + ch);
                        break; 
                }

                startPos = pos + 1;
                if (startPos >= cch) 
                    break;
 
                pos = IndexOfHtmlAttributeEncodingChars(s, startPos); 
                if (pos == -1) {
                    builder.Append(s, startPos, cch - startPos); 
                    break;
                }
            }
 
            return builder.ToString();
        } 
 
        internal static void HtmlAttributeEncodeInternal(String s, HttpWriter writer) {
            int pos = IndexOfHtmlAttributeEncodingChars(s, 0); 
            if (pos == -1) {
                writer.Write(s);
                return;
            } 

            int cch = s.Length; 
            int startPos = 0; 
            for (;;) {
                if (pos > startPos) { 
                    writer.WriteString(s, startPos, pos - startPos);
                }

                char ch = s[pos]; 
                switch (ch) {
                    case '"': 
                        writer.Write("""); 
                        break;
                    case '&': 
                        writer.Write("&");
                        break;
                    case '<':
                        // Whidbey 32404: The character '<' is not valid in an XML attribute value. 
                        // (See the W3C XML rec).
                        writer.Write("<"); 
                        break; 
                }
 
                startPos = pos + 1;
                if (startPos >= cch)
                    break;
 
                pos = IndexOfHtmlAttributeEncodingChars(s, startPos);
                if (pos == -1) { 
                    writer.WriteString(s, startPos, cch - startPos); 
                    break;
                } 
            }
        }

 

        ///  
        ///     
        ///       Encodes a string to make it a valid HTML attribute and returns the output
        ///       to a TextWriter stream of 
        ///       output.
        ///    
        /// 
        public unsafe static void HtmlAttributeEncode(String s, TextWriter output) { 
            if (s == null)
                return; 
 
            int index = IndexOfHtmlAttributeEncodingChars(s, 0);
            if (index == -1) { 
                output.Write(s);
            }
            else {
                int cch = s.Length - index; 
                fixed (char * str = s) {
                    char *pch = str; 
                    while (index-- > 0) { 
                        output.Write(*pch++);
                    } 

                    while (cch-- > 0) {
                        char ch = *pch++;
                        if (ch <= '<') { 
                            switch (ch) {
                                case '<': 
                                    output.Write("<"); 
                                    break;
                                case '"': 
                                    output.Write(""");
                                    break;
                                case '&':
                                    output.Write("&"); 
                                    break;
                                default: 
                                    output.Write(ch); 
                                    break;
                            } 
                        }
                        else {
                            output.Write(ch);
                        } 
                    }
                } 
            } 
        }
 
        static unsafe int IndexOfHtmlAttributeEncodingChars(string s, int startPos) {
            Debug.Assert(0 <= startPos && startPos <= s.Length, "0 <= startPos && startPos <= s.Length");
            int cch = s.Length - startPos;
            fixed (char * str = s) { 
                for (char *pch = &str[startPos]; cch > 0; pch++, cch--) {
                    char ch = *pch; 
                    if (ch <= '<') { 
                        switch (ch) {
                            case '<': 
                            case '"':
                            case '&':
                                return s.Length - cch;
                        } 
                    }
                } 
            } 

            return -1; 
        }


        internal static string FormatPlainTextSpacesAsHtml(string s) { 
            if (s == null) {
                return null; 
            } 

            StringBuilder builder = new StringBuilder(); 
            StringWriter writer = new StringWriter(builder);

            int cb = s.Length;
 
            for (int i = 0; i < cb; i++) {
                char ch = s[i]; 
                if(ch == ' ') { 
                    writer.Write(" ");
                } 
                else {
                    writer.Write(ch);
                }
            } 
            return builder.ToString();
        } 
 
        internal static String FormatPlainTextAsHtml(String s) {
            if (s == null) 
                return null;

            StringBuilder builder = new StringBuilder();
            StringWriter writer = new StringWriter(builder); 

            FormatPlainTextAsHtml(s, writer); 
 
            return builder.ToString();
        } 

        internal static void FormatPlainTextAsHtml(String s, TextWriter output) {
            if (s == null)
                return; 

            int cb = s.Length; 
 
            char prevCh = '\0';
 
            for (int i=0; i': 
                        output.Write(">");
                        break; 
                    case '"':
                        output.Write(""");
                        break;
                    case '&': 
                        output.Write("&");
                        break; 
                    case ' ': 
                        if (prevCh == ' ')
                            output.Write(" "); 
                        else
                            output.Write(ch);
                        break;
                    case '\r': 
                        // Ignore \r, only handle \n
                        break; 
                    case '\n': 
                        output.Write("
"); break; // default: #if ENTITY_ENCODE_HIGH_ASCII_CHARS // The seemingly arbitrary 160 comes from RFC if (ch >= 160 && ch < 256) { output.Write("&#"); output.Write(((int)ch).ToString(NumberFormatInfo.InvariantInfo)); output.Write(';'); break; } #endif // ENTITY_ENCODE_HIGH_ASCII_CHARS output.Write(ch); break; } prevCh = ch; } } ////////////////////////////////////////////////////////////////////////// // // ASII encode - everything all non-7-bit to '?' // /*internal static String AsciiEncode(String s) { if (s == null) return null; StringBuilder sb = new StringBuilder(s.Length); for (int i = 0; i < s.Length; i++) { char ch = s[i]; if (((ch & 0xff80) != 0) || (ch < ' ' && ch != '\r' && ch != '\n' && ch != '\t')) ch = '?'; sb.Append(ch); } return sb.ToString(); }*/ // // Query string parsing support // public static NameValueCollection ParseQueryString(string query) { return ParseQueryString(query, Encoding.UTF8); } public static NameValueCollection ParseQueryString(string query, Encoding encoding) { if (query == null) { throw new ArgumentNullException("query"); } if (encoding == null) { throw new ArgumentNullException("encoding"); } if (query.Length > 0 && query[0] == '?') { query = query.Substring(1); } return new HttpValueCollection(query, false, true, encoding); } ////////////////////////////////////////////////////////////////////////// // // URL decoding / encoding // ////////////////////////////////////////////////////////////////////////// // // Public static methods // /// /// [To be supplied.] /// public static string UrlEncode(string str) { if (str == null) return null; return UrlEncode(str, Encoding.UTF8); } /// /// /// URL encodes a path portion of a URL string and returns the encoded string. /// /// public static string UrlPathEncode(string str) { if (str == null) return null; // recurse in case there is a query string int i = str.IndexOf('?'); if (i >= 0) return UrlPathEncode(str.Substring(0, i)) + str.Substring(i); // encode DBCS characters and spaces only return UrlEncodeSpaces(UrlEncodeNonAscii(str, Encoding.UTF8)); } internal static string AspCompatUrlEncode(string s) { s = UrlEncode(s); s = s.Replace("!", "%21"); s = s.Replace("*", "%2A"); s = s.Replace("(", "%28"); s = s.Replace(")", "%29"); s = s.Replace("-", "%2D"); s = s.Replace(".", "%2E"); s = s.Replace("_", "%5F"); s = s.Replace("\\", "%5C"); return s; } /// /// [To be supplied.] /// public static string UrlEncode(string str, Encoding e) { if (str == null) return null; return Encoding.ASCII.GetString(UrlEncodeToBytes(str, e)); } // Helper to encode the non-ASCII url characters only internal static String UrlEncodeNonAscii(string str, Encoding e) { if (String.IsNullOrEmpty(str)) return str; if (e == null) e = Encoding.UTF8; byte[] bytes = e.GetBytes(str); bytes = UrlEncodeBytesToBytesInternalNonAscii(bytes, 0, bytes.Length, false); return Encoding.ASCII.GetString(bytes); } // Helper to encode spaces only internal static String UrlEncodeSpaces(string str) { if (str != null && str.IndexOf(' ') >= 0) str = str.Replace(" ", "%20"); return str; } /// /// [To be supplied.] /// public static string UrlEncode(byte[] bytes) { if (bytes == null) return null; return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes)); } /// /// [To be supplied.] /// public static string UrlEncode(byte[] bytes, int offset, int count) { if (bytes == null) return null; return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, offset, count)); } /// /// [To be supplied.] /// public static byte[] UrlEncodeToBytes(string str) { if (str == null) return null; return UrlEncodeToBytes(str, Encoding.UTF8); } /// /// [To be supplied.] /// public static byte[] UrlEncodeToBytes(string str, Encoding e) { if (str == null) return null; byte[] bytes = e.GetBytes(str); return UrlEncodeBytesToBytesInternal(bytes, 0, bytes.Length, false); } /// /// [To be supplied.] /// public static byte[] UrlEncodeToBytes(byte[] bytes) { if (bytes == null) return null; return UrlEncodeToBytes(bytes, 0, bytes.Length); } /// /// [To be supplied.] /// public static byte[] UrlEncodeToBytes(byte[] bytes, int offset, int count) { if (bytes == null && count == 0) return null; if (bytes == null) { throw new ArgumentNullException("bytes"); } if (offset < 0 || offset > bytes.Length) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || offset+count > bytes.Length) { throw new ArgumentOutOfRangeException("count"); } return UrlEncodeBytesToBytesInternal(bytes, offset, count, true); } /// /// [To be supplied.] /// public static string UrlEncodeUnicode(string str) { if (str == null) return null; return UrlEncodeUnicodeStringToStringInternal(str, false); } /// /// [To be supplied.] /// public static byte[] UrlEncodeUnicodeToBytes(string str) { if (str == null) return null; return Encoding.ASCII.GetBytes(UrlEncodeUnicode(str)); } /// /// [To be supplied.] /// public static string UrlDecode(string str) { if (str == null) return null; return UrlDecode(str, Encoding.UTF8); } /// /// [To be supplied.] /// public static string UrlDecode(string str, Encoding e) { if (str == null) return null; return UrlDecodeStringFromStringInternal(str, e); } /// /// [To be supplied.] /// public static string UrlDecode(byte[] bytes, Encoding e) { if (bytes == null) return null; return UrlDecode(bytes, 0, bytes.Length, e); } /// /// [To be supplied.] /// public static string UrlDecode(byte[] bytes, int offset, int count, Encoding e) { if (bytes == null && count == 0) return null; if (bytes == null) { throw new ArgumentNullException("bytes"); } if (offset < 0 || offset > bytes.Length) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || offset+count > bytes.Length) { throw new ArgumentOutOfRangeException("count"); } return UrlDecodeStringFromBytesInternal(bytes, offset, count, e); } /// /// [To be supplied.] /// public static byte[] UrlDecodeToBytes(string str) { if (str == null) return null; return UrlDecodeToBytes(str, Encoding.UTF8); } /// /// [To be supplied.] /// public static byte[] UrlDecodeToBytes(string str, Encoding e) { if (str == null) return null; return UrlDecodeToBytes(e.GetBytes(str)); } /// /// [To be supplied.] /// public static byte[] UrlDecodeToBytes(byte[] bytes) { if (bytes == null) return null; return UrlDecodeToBytes(bytes, 0, (bytes != null) ? bytes.Length : 0); } /// /// [To be supplied.] /// public static byte[] UrlDecodeToBytes(byte[] bytes, int offset, int count) { if (bytes == null && count == 0) return null; if (bytes == null) { throw new ArgumentNullException("bytes"); } if (offset < 0 || offset > bytes.Length) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || offset+count > bytes.Length) { throw new ArgumentOutOfRangeException("count"); } return UrlDecodeBytesFromBytesInternal(bytes, offset, count); } // // Implementation for encoding // private static byte[] UrlEncodeBytesToBytesInternal(byte[] bytes, int offset, int count, bool alwaysCreateReturnValue) { int cSpaces = 0; int cUnsafe = 0; // count them first for (int i = 0; i < count; i++) { char ch = (char)bytes[offset+i]; if (ch == ' ') cSpaces++; else if (!IsSafe(ch)) cUnsafe++; } // nothing to expand? if (!alwaysCreateReturnValue && cSpaces == 0 && cUnsafe == 0) return bytes; // expand not 'safe' characters into %XX, spaces to +s byte[] expandedBytes = new byte[count + cUnsafe*2]; int pos = 0; for (int i = 0; i < count; i++) { byte b = bytes[offset+i]; char ch = (char)b; if (IsSafe(ch)) { expandedBytes[pos++] = b; } else if (ch == ' ') { expandedBytes[pos++] = (byte)'+'; } else { expandedBytes[pos++] = (byte)'%'; expandedBytes[pos++] = (byte)IntToHex((b >> 4) & 0xf); expandedBytes[pos++] = (byte)IntToHex(b & 0x0f); } } return expandedBytes; } private static bool IsNonAsciiByte(byte b) { return ( b >= 0x7F || b < 0x20 ); } private static byte[] UrlEncodeBytesToBytesInternalNonAscii(byte[] bytes, int offset, int count, bool alwaysCreateReturnValue) { int cNonAscii = 0; // count them first for (int i = 0; i < count; i++) { if ( IsNonAsciiByte(bytes[offset+i]) ) cNonAscii++; } // nothing to expand? if (!alwaysCreateReturnValue && cNonAscii == 0) return bytes; // expand not 'safe' characters into %XX, spaces to +s byte[] expandedBytes = new byte[count + cNonAscii*2]; int pos = 0; for (int i = 0; i < count; i++) { byte b = bytes[offset+i]; if (IsNonAsciiByte(b)) { expandedBytes[pos++] = (byte)'%'; expandedBytes[pos++] = (byte)IntToHex((b >> 4) & 0xf); expandedBytes[pos++] = (byte)IntToHex(b & 0x0f); } else { expandedBytes[pos++] = b; } } return expandedBytes; } private static string UrlEncodeUnicodeStringToStringInternal(string s, bool ignoreAscii) { int l = s.Length; StringBuilder sb = new StringBuilder(l); for (int i = 0; i < l; i++) { char ch = s[i]; if ((ch & 0xff80) == 0) { // 7 bit? if (ignoreAscii || IsSafe(ch)) { sb.Append(ch); } else if (ch == ' ') { sb.Append('+'); } else { sb.Append('%'); sb.Append(IntToHex((ch >> 4) & 0xf)); sb.Append(IntToHex((ch ) & 0xf)); } } else { // arbitrary Unicode? sb.Append("%u"); sb.Append(IntToHex((ch >> 12) & 0xf)); sb.Append(IntToHex((ch >> 8) & 0xf)); sb.Append(IntToHex((ch >> 4) & 0xf)); sb.Append(IntToHex((ch ) & 0xf)); } } return sb.ToString(); } // // Implementation for decoding // // Internal class to facilitate URL decoding -- keeps char buffer and byte buffer, allows appending of either chars or bytes private class UrlDecoder { private int _bufferSize; // Accumulate characters in a special array private int _numChars; private char[] _charBuffer; // Accumulate bytes for decoding into characters in a special array private int _numBytes; private byte[] _byteBuffer; // Encoding to convert chars to bytes private Encoding _encoding; private void FlushBytes() { if (_numBytes > 0) { _numChars += _encoding.GetChars(_byteBuffer, 0, _numBytes, _charBuffer, _numChars); _numBytes = 0; } } internal UrlDecoder(int bufferSize, Encoding encoding) { _bufferSize = bufferSize; _encoding = encoding; _charBuffer = new char[bufferSize]; // byte buffer created on demand } internal void AddChar(char ch) { if (_numBytes > 0) FlushBytes(); _charBuffer[_numChars++] = ch; } internal void AddByte(byte b) { // if there are no pending bytes treat 7 bit bytes as characters // this optimization is temp disable as it doesn't work for some encodings /* if (_numBytes == 0 && ((b & 0x80) == 0)) { AddChar((char)b); } else */ { if (_byteBuffer == null) _byteBuffer = new byte[_bufferSize]; _byteBuffer[_numBytes++] = b; } } internal String GetString() { if (_numBytes > 0) FlushBytes(); if (_numChars > 0) return new String(_charBuffer, 0, _numChars); else return String.Empty; } } internal static string CollapsePercentUFromStringInternal(string s, Encoding e) { int count = s.Length; UrlDecoder helper = new UrlDecoder(count, e); // go thorugh the string's chars collapsing just %uXXXX and // appending each char as char int loc = s.IndexOf("%u", StringComparison.Ordinal); if(loc == -1) { return s; } for (int pos = 0; pos < count; pos++) { char ch = s[pos]; if (ch == '%' && pos < count-5) { if(s[pos+1] == 'u') { int h1 = HexToInt(s[pos+2]); int h2 = HexToInt(s[pos+3]); int h3 = HexToInt(s[pos+4]); int h4 = HexToInt(s[pos+5]); if (h1 >= 0 && h2 >= 0 && h3 >= 0 && h4 >= 0) { //valid 4 hex chars ch = (char)((h1 << 12) | (h2 << 8) | (h3 << 4) | h4); pos += 5; // add as char helper.AddChar(ch); continue; } } } if ((ch & 0xFF80) == 0) helper.AddByte((byte)ch); // 7 bit have to go as bytes because of Unicode else helper.AddChar(ch); } return helper.GetString(); } private static string UrlDecodeStringFromStringInternal(string s, Encoding e) { int count = s.Length; UrlDecoder helper = new UrlDecoder(count, e); // go through the string's chars collapsing %XX and %uXXXX and // appending each char as char, with exception of %XX constructs // that are appended as bytes for (int pos = 0; pos < count; pos++) { char ch = s[pos]; if (ch == '+') { ch = ' '; } else if (ch == '%' && pos < count-2) { if (s[pos+1] == 'u' && pos < count-5) { int h1 = HexToInt(s[pos+2]); int h2 = HexToInt(s[pos+3]); int h3 = HexToInt(s[pos+4]); int h4 = HexToInt(s[pos+5]); if (h1 >= 0 && h2 >= 0 && h3 >= 0 && h4 >= 0) { // valid 4 hex chars ch = (char)((h1 << 12) | (h2 << 8) | (h3 << 4) | h4); pos += 5; // only add as char helper.AddChar(ch); continue; } } else { int h1 = HexToInt(s[pos+1]); int h2 = HexToInt(s[pos+2]); if (h1 >= 0 && h2 >= 0) { // valid 2 hex chars byte b = (byte)((h1 << 4) | h2); pos += 2; // don't add as char helper.AddByte(b); continue; } } } if ((ch & 0xFF80) == 0) helper.AddByte((byte)ch); // 7 bit have to go as bytes because of Unicode else helper.AddChar(ch); } return helper.GetString(); } private static string UrlDecodeStringFromBytesInternal(byte[] buf, int offset, int count, Encoding e) { UrlDecoder helper = new UrlDecoder(count, e); // go through the bytes collapsing %XX and %uXXXX and appending // each byte as byte, with exception of %uXXXX constructs that // are appended as chars for (int i = 0; i < count; i++) { int pos = offset + i; byte b = buf[pos]; // The code assumes that + and % cannot be in multibyte sequence if (b == '+') { b = (byte)' '; } else if (b == '%' && i < count-2) { if (buf[pos+1] == 'u' && i < count-5) { int h1 = HexToInt((char)buf[pos+2]); int h2 = HexToInt((char)buf[pos+3]); int h3 = HexToInt((char)buf[pos+4]); int h4 = HexToInt((char)buf[pos+5]); if (h1 >= 0 && h2 >= 0 && h3 >= 0 && h4 >= 0) { // valid 4 hex chars char ch = (char)((h1 << 12) | (h2 << 8) | (h3 << 4) | h4); i += 5; // don't add as byte helper.AddChar(ch); continue; } } else { int h1 = HexToInt((char)buf[pos+1]); int h2 = HexToInt((char)buf[pos+2]); if (h1 >= 0 && h2 >= 0) { // valid 2 hex chars b = (byte)((h1 << 4) | h2); i += 2; } } } helper.AddByte(b); } return helper.GetString(); } private static byte[] UrlDecodeBytesFromBytesInternal(byte[] buf, int offset, int count) { int decodedBytesCount = 0; byte[] decodedBytes = new byte[count]; for (int i = 0; i < count; i++) { int pos = offset + i; byte b = buf[pos]; if (b == '+') { b = (byte)' '; } else if (b == '%' && i < count-2) { int h1 = HexToInt((char)buf[pos+1]); int h2 = HexToInt((char)buf[pos+2]); if (h1 >= 0 && h2 >= 0) { // valid 2 hex chars b = (byte)((h1 << 4) | h2); i += 2; } } decodedBytes[decodedBytesCount++] = b; } if (decodedBytesCount < decodedBytes.Length) { byte[] newDecodedBytes = new byte[decodedBytesCount]; Array.Copy(decodedBytes, newDecodedBytes, decodedBytesCount); decodedBytes = newDecodedBytes; } return decodedBytes; } // // Private helpers for URL encoding/decoding // private static int HexToInt(char h) { return( h >= '0' && h <= '9' ) ? h - '0' : ( h >= 'a' && h <= 'f' ) ? h - 'a' + 10 : ( h >= 'A' && h <= 'F' ) ? h - 'A' + 10 : -1; } internal static char IntToHex(int n) { Debug.Assert(n < 0x10); if (n <= 9) return(char)(n + (int)'0'); else return(char)(n - 10 + (int)'a'); } // Set of safe chars, from RFC 1738.4 minus '+' internal static bool IsSafe(char ch) { if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9') return true; switch (ch) { case '-': case '_': case '.': case '!': case '*': case '\'': case '(': case ')': return true; } return false; } ////////////////////////////////////////////////////////////////////////// // // Misc helpers // ////////////////////////////////////////////////////////////////////////// internal static String FormatHttpDateTime(DateTime dt) { if (dt < DateTime.MaxValue.AddDays(-1) && dt > DateTime.MinValue.AddDays(1)) dt = dt.ToUniversalTime(); return dt.ToString("R", DateTimeFormatInfo.InvariantInfo); } internal static String FormatHttpDateTimeUtc(DateTime dt) { return dt.ToString("R", DateTimeFormatInfo.InvariantInfo); } internal static String FormatHttpCookieDateTime(DateTime dt) { if (dt < DateTime.MaxValue.AddDays(-1) && dt > DateTime.MinValue.AddDays(1)) dt = dt.ToUniversalTime(); return dt.ToString("ddd, dd-MMM-yyyy HH':'mm':'ss 'GMT'", DateTimeFormatInfo.InvariantInfo); } } // helper class for lookup of HTML encoding entities internal class HtmlEntities { private static object _lookupLockObject = new object(); // The list is from http://www.w3.org/TR/REC-html40/sgml/entities.html private static String[] _entitiesList = new String[] { "\x0022-quot", "\x0026-amp", "\x003c-lt", "\x003e-gt", "\x00a0-nbsp", "\x00a1-iexcl", "\x00a2-cent", "\x00a3-pound", "\x00a4-curren", "\x00a5-yen", "\x00a6-brvbar", "\x00a7-sect", "\x00a8-uml", "\x00a9-copy", "\x00aa-ordf", "\x00ab-laquo", "\x00ac-not", "\x00ad-shy", "\x00ae-reg", "\x00af-macr", "\x00b0-deg", "\x00b1-plusmn", "\x00b2-sup2", "\x00b3-sup3", "\x00b4-acute", "\x00b5-micro", "\x00b6-para", "\x00b7-middot", "\x00b8-cedil", "\x00b9-sup1", "\x00ba-ordm", "\x00bb-raquo", "\x00bc-frac14", "\x00bd-frac12", "\x00be-frac34", "\x00bf-iquest", "\x00c0-Agrave", "\x00c1-Aacute", "\x00c2-Acirc", "\x00c3-Atilde", "\x00c4-Auml", "\x00c5-Aring", "\x00c6-AElig", "\x00c7-Ccedil", "\x00c8-Egrave", "\x00c9-Eacute", "\x00ca-Ecirc", "\x00cb-Euml", "\x00cc-Igrave", "\x00cd-Iacute", "\x00ce-Icirc", "\x00cf-Iuml", "\x00d0-ETH", "\x00d1-Ntilde", "\x00d2-Ograve", "\x00d3-Oacute", "\x00d4-Ocirc", "\x00d5-Otilde", "\x00d6-Ouml", "\x00d7-times", "\x00d8-Oslash", "\x00d9-Ugrave", "\x00da-Uacute", "\x00db-Ucirc", "\x00dc-Uuml", "\x00dd-Yacute", "\x00de-THORN", "\x00df-szlig", "\x00e0-agrave", "\x00e1-aacute", "\x00e2-acirc", "\x00e3-atilde", "\x00e4-auml", "\x00e5-aring", "\x00e6-aelig", "\x00e7-ccedil", "\x00e8-egrave", "\x00e9-eacute", "\x00ea-ecirc", "\x00eb-euml", "\x00ec-igrave", "\x00ed-iacute", "\x00ee-icirc", "\x00ef-iuml", "\x00f0-eth", "\x00f1-ntilde", "\x00f2-ograve", "\x00f3-oacute", "\x00f4-ocirc", "\x00f5-otilde", "\x00f6-ouml", "\x00f7-divide", "\x00f8-oslash", "\x00f9-ugrave", "\x00fa-uacute", "\x00fb-ucirc", "\x00fc-uuml", "\x00fd-yacute", "\x00fe-thorn", "\x00ff-yuml", "\x0152-OElig", "\x0153-oelig", "\x0160-Scaron", "\x0161-scaron", "\x0178-Yuml", "\x0192-fnof", "\x02c6-circ", "\x02dc-tilde", "\x0391-Alpha", "\x0392-Beta", "\x0393-Gamma", "\x0394-Delta", "\x0395-Epsilon", "\x0396-Zeta", "\x0397-Eta", "\x0398-Theta", "\x0399-Iota", "\x039a-Kappa", "\x039b-Lambda", "\x039c-Mu", "\x039d-Nu", "\x039e-Xi", "\x039f-Omicron", "\x03a0-Pi", "\x03a1-Rho", "\x03a3-Sigma", "\x03a4-Tau", "\x03a5-Upsilon", "\x03a6-Phi", "\x03a7-Chi", "\x03a8-Psi", "\x03a9-Omega", "\x03b1-alpha", "\x03b2-beta", "\x03b3-gamma", "\x03b4-delta", "\x03b5-epsilon", "\x03b6-zeta", "\x03b7-eta", "\x03b8-theta", "\x03b9-iota", "\x03ba-kappa", "\x03bb-lambda", "\x03bc-mu", "\x03bd-nu", "\x03be-xi", "\x03bf-omicron", "\x03c0-pi", "\x03c1-rho", "\x03c2-sigmaf", "\x03c3-sigma", "\x03c4-tau", "\x03c5-upsilon", "\x03c6-phi", "\x03c7-chi", "\x03c8-psi", "\x03c9-omega", "\x03d1-thetasym", "\x03d2-upsih", "\x03d6-piv", "\x2002-ensp", "\x2003-emsp", "\x2009-thinsp", "\x200c-zwnj", "\x200d-zwj", "\x200e-lrm", "\x200f-rlm", "\x2013-ndash", "\x2014-mdash", "\x2018-lsquo", "\x2019-rsquo", "\x201a-sbquo", "\x201c-ldquo", "\x201d-rdquo", "\x201e-bdquo", "\x2020-dagger", "\x2021-Dagger", "\x2022-bull", "\x2026-hellip", "\x2030-permil", "\x2032-prime", "\x2033-Prime", "\x2039-lsaquo", "\x203a-rsaquo", "\x203e-oline", "\x2044-frasl", "\x20ac-euro", "\x2111-image", "\x2118-weierp", "\x211c-real", "\x2122-trade", "\x2135-alefsym", "\x2190-larr", "\x2191-uarr", "\x2192-rarr", "\x2193-darr", "\x2194-harr", "\x21b5-crarr", "\x21d0-lArr", "\x21d1-uArr", "\x21d2-rArr", "\x21d3-dArr", "\x21d4-hArr", "\x2200-forall", "\x2202-part", "\x2203-exist", "\x2205-empty", "\x2207-nabla", "\x2208-isin", "\x2209-notin", "\x220b-ni", "\x220f-prod", "\x2211-sum", "\x2212-minus", "\x2217-lowast", "\x221a-radic", "\x221d-prop", "\x221e-infin", "\x2220-ang", "\x2227-and", "\x2228-or", "\x2229-cap", "\x222a-cup", "\x222b-int", "\x2234-there4", "\x223c-sim", "\x2245-cong", "\x2248-asymp", "\x2260-ne", "\x2261-equiv", "\x2264-le", "\x2265-ge", "\x2282-sub", "\x2283-sup", "\x2284-nsub", "\x2286-sube", "\x2287-supe", "\x2295-oplus", "\x2297-otimes", "\x22a5-perp", "\x22c5-sdot", "\x2308-lceil", "\x2309-rceil", "\x230a-lfloor", "\x230b-rfloor", "\x2329-lang", "\x232a-rang", "\x25ca-loz", "\x2660-spades", "\x2663-clubs", "\x2665-hearts", "\x2666-diams", }; private static Hashtable _entitiesLookupTable; private HtmlEntities() { } internal /*public*/ static char Lookup(String entity) { if (_entitiesLookupTable == null) { // populate hashtable on demand lock (_lookupLockObject) { if (_entitiesLookupTable == null) { Hashtable t = new Hashtable(); foreach (String s in _entitiesList) t[s.Substring(2)] = s[0]; // 1st char is the code, 2nd '-' _entitiesLookupTable = t; } } } Object obj = _entitiesLookupTable[entity]; if (obj != null) return (char)obj; else return (char)0; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* * Server intrinsic used to match ASP's object model * * Copyright (c) 1999 Microsoft Corporation */ // Don't entity encode high chars (160 to 256), to fix bugs VSWhidbey 85857/111927 // #define ENTITY_ENCODE_HIGH_ASCII_CHARS namespace System.Web { using System.Text; using System.Runtime.Serialization.Formatters; using System.Threading; using System.Runtime.InteropServices; using System.IO; using System.Collections; using System.Collections.Specialized; using System.Globalization; using System.Web.Hosting; using System.Web.Util; using System.Web.UI; using System.Web.Configuration; using System.Security; using System.Security.Permissions; using System.Web.Management; using System.Web.SessionState; internal abstract class ErrorFormatterGenerator { internal abstract ErrorFormatter GetErrorFormatter(Exception e); } /// /// /// Provides several /// helper methods that can be used in the processing of Web requests. /// /// [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] public sealed class HttpServerUtility { private HttpContext _context; private HttpApplication _application; private static IDictionary _cultureCache = Hashtable.Synchronized(new Hashtable()); internal HttpServerUtility(HttpContext context) { _context = context; } internal HttpServerUtility(HttpApplication application) { _application = application; } // // Misc ASP compatibility methods // /// /// /// Instantiates a COM object identified via a progid. /// /// [SecurityPermission(SecurityAction.Demand, Unrestricted = true)] public object CreateObject(string progID) { Type type = null; object obj = null; try { #if !FEATURE_PAL // FEATURE_PAL does not enable COM type = Type.GetTypeFromProgID(progID); #else // !FEATURE_PAL throw new NotImplementedException("ROTORTODO"); #endif // !FEATURE_PAL } catch { } if (type == null) { throw new HttpException(SR.GetString(SR.Could_not_create_object_of_type, progID)); } // Disallow Apartment components in non-compat mode AspCompatApplicationStep.CheckThreadingModel(progID, type.GUID); // Instantiate the object obj = Activator.CreateInstance(type); // For ASP compat: take care of OnPageStart/OnPageEnd AspCompatApplicationStep.OnPageStart(obj); return obj; } /// /// /// Instantiates a COM object identified via a Type. /// /// [SecurityPermission(SecurityAction.Demand, UnmanagedCode=true)] public object CreateObject(Type type) { // Disallow Apartment components in non-compat mode AspCompatApplicationStep.CheckThreadingModel(type.FullName, type.GUID); // Instantiate the object Object obj = Activator.CreateInstance(type); // For ASP compat: take care of OnPageStart/OnPageEnd AspCompatApplicationStep.OnPageStart(obj); return obj; } /// /// /// Instantiates a COM object identified via a clsid. /// /// [SecurityPermission(SecurityAction.Demand, UnmanagedCode=true)] public object CreateObjectFromClsid(string clsid) { Type type = null; object obj = null; // Create a Guid out of it Guid guid = new Guid(clsid); // Disallow Apartment components in non-compat mode AspCompatApplicationStep.CheckThreadingModel(clsid, guid); try { #if !FEATURE_PAL // FEATURE_PAL does not enable COM type = Type.GetTypeFromCLSID(guid, null, true /*throwOnError*/); #else // !FEATURE_PAL throw new NotImplementedException("ROTORTODO"); #endif // !FEATURE_PAL // Instantiate the object obj = Activator.CreateInstance(type); } catch { } if (obj == null) { throw new HttpException( SR.GetString(SR.Could_not_create_object_from_clsid, clsid)); } // For ASP compat: take care of OnPageStart/OnPageEnd AspCompatApplicationStep.OnPageStart(obj); return obj; } // Internal static method that returns a read-only, non-user override accounted, CultureInfo object internal static CultureInfo CreateReadOnlyCultureInfo(string name) { if (!_cultureCache.Contains(name)) { // To be threadsafe, get the lock before creating lock (_cultureCache) { if (_cultureCache[name] == null) { _cultureCache[name] = CultureInfo.ReadOnly(new CultureInfo(name)); } } } return (CultureInfo)_cultureCache[name]; } // Internal static method that returns a read-only, non-user override accounted, culture specific CultureInfo object internal static CultureInfo CreateReadOnlySpecificCultureInfo(string name) { if(name.IndexOf('-') > 0) { return CreateReadOnlyCultureInfo(name); } CultureInfo ci = CultureInfo.CreateSpecificCulture(name); if (!_cultureCache.Contains(ci.Name)) { //To be threadsafe, get the lock before creating lock (_cultureCache) { if (_cultureCache[ci.Name] == null) { _cultureCache[ci.Name] = CultureInfo.ReadOnly(ci); } } } return (CultureInfo)_cultureCache[ci.Name]; } // Internal static method that returns a read-only, non-user override accounted, CultureInfo object internal static CultureInfo CreateReadOnlyCultureInfo(int culture) { if (!_cultureCache.Contains(culture)) { // To be threadsafe, get the lock before creating lock (_cultureCache) { if (_cultureCache[culture] == null) { _cultureCache[culture] = CultureInfo.ReadOnly(new CultureInfo(culture)); } } } return (CultureInfo)_cultureCache[culture]; } /// /// /// Maps a virtual path to a physical path. /// /// public string MapPath(string path) { if (_context == null) throw new HttpException(SR.GetString(SR.Server_not_available)); // Disable hiding the request so that Server.MapPath works when called from // Application_Start in integrated mode bool unhideRequest = _context.HideRequestResponse; string realPath; try { if (unhideRequest) { _context.HideRequestResponse = false; } realPath = _context.Request.MapPath(path); } finally { if (unhideRequest) { _context.HideRequestResponse = true; } } return realPath; } /// /// Returns the last recorded exception. /// public Exception GetLastError() { if (_context != null) return _context.Error; else if (_application != null) return _application.LastError; else return null; } /// /// Clears the last error. /// public void ClearError() { if (_context != null) _context.ClearError(); else if (_application != null) _application.ClearError(); } // // Server.Transfer/Server.Execute -- child requests // /// /// /// Executes a new request (using the specified URL path as the target). Unlike /// the Transfer method, execution of the original page continues after the executed /// page completes. /// /// public void Execute(string path) { Execute(path, null, true /*preserveForm*/); } /// /// /// Executes a new request (using the specified URL path as the target). Unlike /// the Transfer method, execution of the original page continues after the executed /// page completes. /// /// public void Execute(string path, TextWriter writer) { Execute(path, writer, true /*preserveForm*/); } /// /// /// Executes a new request (using the specified URL path as the target). Unlike /// the Transfer method, execution of the original page continues after the executed /// page completes. /// If preserveForm is false, the QueryString and Form collections are cleared. /// /// public void Execute(string path, bool preserveForm) { Execute(path, null, preserveForm); } /// /// /// Executes a new request (using the specified URL path as the target). Unlike /// the Transfer method, execution of the original page continues after the executed /// page completes. /// If preserveForm is false, the QueryString and Form collections are cleared. /// /// public void Execute(string path, TextWriter writer, bool preserveForm) { if (_context == null) throw new HttpException(SR.GetString(SR.Server_not_available)); if (path == null) throw new ArgumentNullException("path"); string queryStringOverride = null; HttpRequest request = _context.Request; HttpResponse response = _context.Response; // Remove potential cookie-less session id (ASURT 100558) path = response.RemoveAppPathModifier(path); // Allow query string override int iqs = path.IndexOf('?'); if (iqs >= 0) { queryStringOverride = path.Substring(iqs+1); path = path.Substring(0, iqs); } if (!UrlPath.IsValidVirtualPathWithoutProtocol(path)) throw new ArgumentException(SR.GetString(SR.Invalid_path_for_child_request, path)); VirtualPath virtualPath = VirtualPath.Create(path); // Find the handler for the path IHttpHandler handler = null; string physPath = request.MapPath(virtualPath); // get physical path VirtualPath filePath = request.FilePathObject.Combine(virtualPath); // vpath // Demand read access to the physical path of the target handler InternalSecurityPermissions.FileReadAccess(physPath).Demand(); // We need to Assert since there typically is user code on the stack (VSWhidbey 270965) InternalSecurityPermissions.Unrestricted.Assert(); try { // paths that ends with . are disallowed as they are used to get around // extension mappings and server source as static file if (StringUtil.StringEndsWith(virtualPath.VirtualPathString, '.')) throw new HttpException(404, String.Empty); bool useAppConfig = !filePath.IsWithinAppRoot; using (new HttpContextWrapper(_context)) { try { // We need to increase the depth when calling MapHttpHandler, // since PageHandlerFactory relies on it _context.ServerExecuteDepth++; if (_context.WorkerRequest is IIS7WorkerRequest) { handler = _context.ApplicationInstance.MapIntegratedHttpHandler( _context, request.RequestType, filePath, physPath, useAppConfig, true /*convertNativeStaticFileModule*/); } else { handler = _context.ApplicationInstance.MapHttpHandler( _context, request.RequestType, filePath, physPath, useAppConfig); } } finally { _context.ServerExecuteDepth--; } } } catch (Exception e) { // 500 errors (compilation errors) get preserved if (e is HttpException) { int code = ((HttpException)e).GetHttpCode(); if (code != 500 && code != 404) { e = null; } } throw new HttpException(SR.GetString(SR.Error_executing_child_request_for_path, path), e); } ExecuteInternal(handler, writer, preserveForm, true /*setPreviousPage*/, virtualPath, filePath, physPath, null, queryStringOverride); } public void Execute(IHttpHandler handler, TextWriter writer, bool preserveForm) { if (_context == null) throw new HttpException(SR.GetString(SR.Server_not_available)); Execute(handler, writer, preserveForm, true /*setPreviousPage*/); } internal void Execute(IHttpHandler handler, TextWriter writer, bool preserveForm, bool setPreviousPage) { HttpRequest request = _context.Request; VirtualPath filePath = request.CurrentExecutionFilePathObject; string physicalPath = request.MapPath(filePath); ExecuteInternal(handler, writer, preserveForm, setPreviousPage, null, filePath, physicalPath, null, null); } private void ExecuteInternal(IHttpHandler handler, TextWriter writer, bool preserveForm, bool setPreviousPage, VirtualPath path, VirtualPath filePath, string physPath, Exception error, string queryStringOverride) { if (handler == null) throw new ArgumentNullException("handler"); HttpRequest request = _context.Request; HttpResponse response = _context.Response; HttpApplication app = _context.ApplicationInstance; HttpValueCollection savedForm = null; VirtualPath savedCurrentExecutionFilePath = null; string savedQueryString = null; TextWriter savedOutputWriter = null; AspNetSynchronizationContext savedSyncContext = null; // Transaction wouldn't flow into ASPCOMPAT mode -- need to report an error VerifyTransactionFlow(handler); // create new trace context _context.PushTraceContext(); // set the new handler as the current handler _context.SetCurrentHandler(handler); // because we call this synchrnously async operations must be disabled bool originalSyncContextWasEnabled = _context.SyncContext.Enabled; _context.SyncContext.Disable(); // Execute the handler try { try { _context.ServerExecuteDepth++; savedCurrentExecutionFilePath = request.SwitchCurrentExecutionFilePath(filePath); if (!preserveForm) { savedForm = request.SwitchForm(new HttpValueCollection()); // Clear out the query string, but honor overrides if (queryStringOverride == null) queryStringOverride = String.Empty; } // override query string if requested if (queryStringOverride != null) { savedQueryString = request.QueryStringText; request.QueryStringText = queryStringOverride; } // capture output if requested if (writer != null) savedOutputWriter = response.SwitchWriter(writer); Page targetPage = handler as Page; if (targetPage != null) { if (setPreviousPage) { // Set the previousPage of the new Page as the previous Page targetPage.SetPreviousPage(_context.PreviousHandler as Page); } Page sourcePage = _context.Handler as Page; #pragma warning disable 0618 // To avoid deprecation warning // If the source page of the transfer has smart nav on, // always do as if the destination has it too (ASURT 97732) if (sourcePage != null && sourcePage.SmartNavigation) targetPage.SmartNavigation = true; #pragma warning restore 0618 // If the target page is async need to save/restore [....] context if (targetPage is IHttpAsyncHandler) { savedSyncContext = _context.InstallNewAspNetSynchronizationContext(); } } if ((handler is StaticFileHandler || handler is DefaultHttpHandler) && !DefaultHttpHandler.IsClassicAspRequest(filePath.VirtualPathString)) { // cannot apply static files handler directly // -- it would dump the source of the current page // instead just dump the file content into response try { response.WriteFile(physPath); } catch { // hide the real error as it could be misleading // in case of mismapped requests like /foo.asmx/bar error = new HttpException(404, String.Empty); } } else if (!(handler is Page)) { // disallow anything but pages error = new HttpException(404, String.Empty); } else if (handler is IHttpAsyncHandler) { // Asynchronous handler // suspend cancellable period (don't abort this thread while // we wait for another to finish) bool isCancellable = _context.IsInCancellablePeriod; if (isCancellable) _context.EndCancellablePeriod(); try { IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler)handler; IAsyncResult ar = asyncHandler.BeginProcessRequest(_context, null, null); // wait for completion if (!ar.IsCompleted) { // suspend app lock while waiting bool needToRelock = false; try { try {} finally { Monitor.Exit(app); needToRelock = true; } WaitHandle h = ar.AsyncWaitHandle; if (h != null) { h.WaitOne(); } else { while (!ar.IsCompleted) Thread.Sleep(1); } } finally { if (needToRelock) { Monitor.Enter(app); } } } // end the async operation (get error if any) try { asyncHandler.EndProcessRequest(ar); } catch (Exception e) { error = e; } } finally { // resume cancelleable period if (isCancellable) _context.BeginCancellablePeriod(); } } else { // Synchronous handler using (new HttpContextWrapper(_context)) { try { handler.ProcessRequest(_context); } catch (Exception e) { error = e; } } } } finally { _context.ServerExecuteDepth--; // Restore the handlers; _context.RestoreCurrentHandler(); // restore output writer if (savedOutputWriter != null) response.SwitchWriter(savedOutputWriter); // restore overriden query string if (queryStringOverride != null && savedQueryString != null) request.QueryStringText = savedQueryString; if (savedForm != null) request.SwitchForm(savedForm); request.SwitchCurrentExecutionFilePath(savedCurrentExecutionFilePath); if (savedSyncContext != null) { _context.RestoreSavedAspNetSynchronizationContext(savedSyncContext); } if (originalSyncContextWasEnabled) { _context.SyncContext.Enable(); } // restore trace context _context.PopTraceContext(); } } catch { // Protect against exception filters throw; } // Report any error if (error != null) { // suppress errors with HTTP codes (for child requests they mislead more than help) if (error is HttpException && ((HttpException)error).GetHttpCode() != 500) error = null; if (path != null) throw new HttpException(SR.GetString(SR.Error_executing_child_request_for_path, path), error); throw new HttpException(SR.GetString(SR.Error_executing_child_request_for_handler, handler.GetType().ToString()), error); } } /// /// /// Terminates execution of the current page and begins execution of a new /// request using the supplied URL path. /// If preserveForm is false, the QueryString and Form collections are cleared. /// /// public void Transfer(string path, bool preserveForm) { Page page = _context.Handler as Page; if ((page != null) && page.IsCallback) { throw new ApplicationException(SR.GetString(SR.Transfer_not_allowed_in_callback)); } // execute child request Execute(path, null, preserveForm); // suppress the remainder of the current one _context.Response.End(); } /// /// /// Terminates execution of the current page and begins execution of a new /// request using the supplied URL path. /// /// public void Transfer(string path) { // Make sure the transfer is not treated as a postback, which could cause a stack // overflow if the user doesn't expect it (VSWhidbey 181013). // If the use *does* want it treated as a postback, they can call Transfer(path, true). bool savedPreventPostback = _context.PreventPostback; _context.PreventPostback = true; Transfer(path, true /*preserveForm*/); _context.PreventPostback = savedPreventPostback; } public void Transfer(IHttpHandler handler, bool preserveForm) { Page page = handler as Page; if ((page != null) && page.IsCallback) { throw new ApplicationException(SR.GetString(SR.Transfer_not_allowed_in_callback)); } Execute(handler, null, preserveForm); // suppress the remainder of the current one _context.Response.End(); } public void TransferRequest(string path) { TransferRequest(path, false, null, null); } public void TransferRequest(string path, bool preserveForm) { TransferRequest(path, preserveForm, null, null); } public void TransferRequest(string path, bool preserveForm, string method, NameValueCollection headers) { if (!HttpRuntime.UseIntegratedPipeline) { throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); } if (_context == null) { throw new HttpException(SR.GetString(SR.Server_not_available)); } if (path == null) { throw new ArgumentNullException("path"); } IIS7WorkerRequest wr = _context.WorkerRequest as IIS7WorkerRequest; HttpRequest request = _context.Request; HttpResponse response = _context.Response; if (wr == null) { throw new HttpException(SR.GetString(SR.Server_not_available)); } // Remove potential cookie-less session id (ASURT 100558) path = response.RemoveAppPathModifier(path); // Extract query string if specified String qs = null; int iqs = path.IndexOf('?'); if (iqs >= 0) { qs = (iqs < path.Length-1) ? path.Substring(iqs+1) : String.Empty; path = path.Substring(0, iqs); } if (!UrlPath.IsValidVirtualPathWithoutProtocol(path)) { throw new ArgumentException(SR.GetString(SR.Invalid_path_for_child_request, path)); } VirtualPath virtualPath = request.FilePathObject.Combine(VirtualPath.Create(path)); string physPath = request.MapPath(path); // Demand read access to the physical path of the target handler InternalSecurityPermissions.FileReadAccess(physPath).Demand(); // Schedule the child execution wr.ScheduleExecuteUrl( virtualPath.VirtualPathString, qs, method, preserveForm, preserveForm ? request.EntityBody : null, headers); // force the completion of the current request so that the // child execution can be performed immediately after unwind _context.ApplicationInstance.EnsureReleaseState(); // DevDiv Bugs 162750: IIS7 Integrated Mode: TransferRequest performance issue // Instead of calling Response.End we call HttpApplication.CompleteRequest() _context.ApplicationInstance.CompleteRequest(); } private void VerifyTransactionFlow(IHttpHandler handler) { Page topPage = _context.Handler as Page; Page childPage = handler as Page; if (childPage != null && childPage.IsInAspCompatMode && // child page aspcompat topPage != null && !topPage.IsInAspCompatMode && // top page is not aspcompat Transactions.Utils.IsInTransaction) { // we are in transaction throw new HttpException(SR.GetString(SR.Transacted_page_calls_aspcompat)); } } // // Static method to execute a request outside of HttpContext and capture the response // internal static void ExecuteLocalRequestAndCaptureResponse(String path, TextWriter writer, ErrorFormatterGenerator errorFormatterGenerator) { HttpRequest request = new HttpRequest( VirtualPath.CreateAbsolute(path), String.Empty); HttpResponse response = new HttpResponse(writer); HttpContext context = new HttpContext(request, response); HttpApplication app = HttpApplicationFactory.GetApplicationInstance(context) as HttpApplication; context.ApplicationInstance = app; try { context.Server.Execute(path); } catch (HttpException e) { if (errorFormatterGenerator != null) { context.Response.SetOverrideErrorFormatter(errorFormatterGenerator.GetErrorFormatter(e)); } context.Response.ReportRuntimeError(e, false, true); } finally { if (app != null) { context.ApplicationInstance = null; HttpApplicationFactory.RecycleApplicationInstance(app); } } } // // Computer name // private static object _machineNameLock = new object(); private static string _machineName; private const int _maxMachineNameLength = 256; /// /// /// Gets /// the server machine name. /// /// public string MachineName { [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)] get { return GetMachineNameInternal(); } } internal static string GetMachineNameInternal() { if (_machineName != null) return _machineName; lock (_machineNameLock) { if (_machineName != null) return _machineName; StringBuilder buf = new StringBuilder (_maxMachineNameLength); int len = _maxMachineNameLength; if (UnsafeNativeMethods.GetComputerName (buf, ref len) == 0) throw new HttpException (SR.GetString (SR.Get_computer_name_failed)); _machineName = buf.ToString(); } return _machineName; } // // Request Timeout // /// /// /// Request timeout in seconds /// /// public int ScriptTimeout { get { if (_context != null) { return Convert.ToInt32(_context.Timeout.TotalSeconds, CultureInfo.InvariantCulture); } else { return HttpRuntimeSection.DefaultExecutionTimeout; } } [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)] set { if (_context == null) throw new HttpException(SR.GetString(SR.Server_not_available)); if (value <= 0) throw new ArgumentOutOfRangeException("value"); _context.Timeout = new TimeSpan(0, 0, value); } } // // Encoding / Decoding -- wrappers for HttpUtility // /// /// /// HTML /// decodes a given string and /// returns the decoded string. /// /// public string HtmlDecode(string s) { return HttpUtility.HtmlDecode(s); } /// /// /// HTML /// decode a string and send the result to a TextWriter output /// stream. /// /// public void HtmlDecode(string s, TextWriter output) { HttpUtility.HtmlDecode(s, output); } /// /// /// HTML /// encodes a given string and /// returns the encoded string. /// /// public string HtmlEncode(string s) { return HttpUtility.HtmlEncode(s); } /// /// /// HTML /// encodes /// a string and returns the output to a TextWriter stream of output. /// /// public void HtmlEncode(string s, TextWriter output) { HttpUtility.HtmlEncode(s, output); } /// /// /// URL /// encodes a given /// string and returns the encoded string. /// /// public string UrlEncode(string s) { Encoding e = (_context != null) ? _context.Response.ContentEncoding : Encoding.UTF8; return HttpUtility.UrlEncode(s, e); } /// /// /// URL encodes a path portion of a URL string and returns the encoded string. /// /// public string UrlPathEncode(string s) { return HttpUtility.UrlPathEncode(s); } /// /// /// URL /// encodes /// a string and returns the output to a TextWriter output stream. /// /// public void UrlEncode(string s, TextWriter output) { if (s != null) output.Write(UrlEncode(s)); } /// /// /// URL decodes a string and returns the output in a string. /// /// public string UrlDecode(string s) { Encoding e = (_context != null) ? _context.Request.ContentEncoding : Encoding.UTF8; return HttpUtility.UrlDecode(s, e); } /// /// /// URL decodes a string and returns the output as a TextWriter output /// stream. /// /// public void UrlDecode(string s, TextWriter output) { if (s != null) output.Write(UrlDecode(s)); } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// static public string UrlTokenEncode(byte [] input) { if (input == null) throw new ArgumentNullException("input"); if (input.Length < 1) return String.Empty; string base64Str = null; int endPos = 0; char[] base64Chars = null; //////////////////////////////////////////////////////// // Step 1: Do a Base64 encoding base64Str = Convert.ToBase64String(input); if (base64Str == null) return null; //////////////////////////////////////////////////////// // Step 2: Find how many padding chars are present in the end for (endPos = base64Str.Length; endPos > 0; endPos--) { if (base64Str[endPos - 1] != '=') // Found a non-padding char! { break; // Stop here } } //////////////////////////////////////////////////////// // Step 3: Create char array to store all non-padding chars, // plus a char to indicate how many padding chars are needed base64Chars = new char[endPos + 1]; base64Chars[endPos] = (char)((int)'0' + base64Str.Length - endPos); // Store a char at the end, to indicate how many padding chars are needed //////////////////////////////////////////////////////// // Step 3: Copy in the other chars. Transform the "+" to "-", and "/" to "_" for (int iter = 0; iter < endPos; iter++) { char c = base64Str[iter]; switch (c) { case '+': base64Chars[iter] = '-'; break; case '/': base64Chars[iter] = '_'; break; case '=': Debug.Assert (false); base64Chars[iter] = c; break; default: base64Chars[iter] = c; break; } } return new string(base64Chars); } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// static public byte [] UrlTokenDecode(string input) { if (input == null) throw new ArgumentNullException("input"); int len = input.Length; if (len < 1) return new byte[0]; /////////////////////////////////////////////////////////////////// // Step 1: Calculate the number of padding chars to append to this string. // The number of padding chars to append is stored in the last char of the string. int numPadChars = (int)input[len - 1] - (int)'0'; if (numPadChars < 0 || numPadChars > 10) return null; /////////////////////////////////////////////////////////////////// // Step 2: Create array to store the chars (not including the last char) // and the padding chars char[] base64Chars = new char[len - 1 + numPadChars]; //////////////////////////////////////////////////////// // Step 3: Copy in the chars. Transform the "-" to "+", and "*" to "/" for (int iter = 0; iter < len - 1; iter++) { char c = input[iter]; switch (c) { case '-': base64Chars[iter] = '+'; break; case '_': base64Chars[iter] = '/'; break; default: base64Chars[iter] = c; break; } } //////////////////////////////////////////////////////// // Step 4: Add padding chars for (int iter = len - 1; iter < base64Chars.Length; iter++) { base64Chars[iter] = '='; } // Do the actual conversion return Convert.FromBase64CharArray (base64Chars, 0, base64Chars.Length); } } /// /// // VSWhidbey 473228 - removed link demand from HttpUtility for ClickOnce scenario public sealed class HttpUtility { public HttpUtility () {} ////////////////////////////////////////////////////////////////////////// // // HTML Encoding / Decoding // /// /// /// HTML decodes a string and returns the decoded string. /// /// public static string HtmlDecode(string s) { if (s == null) return null; // See if this string needs to be decoded at all. If no // ampersands are found, then no special HTML-encoded chars // are in the string. if (s.IndexOf('&') < 0) return s; StringBuilder builder = new StringBuilder(); StringWriter writer = new StringWriter(builder); HtmlDecode(s, writer); return builder.ToString(); } /// /// /// HTML decode a string and send the result to a TextWriter output stream. /// /// private static char[] s_entityEndingChars = new char[] {';', '&'}; public static void HtmlDecode(string s, TextWriter output) { if (s == null) return; if (s.IndexOf('&') < 0) { output.Write(s); // good as is return; } int l = s.Length; for (int i = 0; i < l; i++) { char ch = s[i]; if (ch == '&') { // We found a '&'. Now look for the next ';' or '&'. The idea is that // if we find another '&' before finding a ';', then this is not an entity, // and the next '&' might start a real entity (VSWhidbey 275184) int index = s.IndexOfAny(s_entityEndingChars, i + 1); if (index > 0 && s[index] == ';') { string entity = s.Substring(i + 1, index - i - 1); if (entity.Length > 1 && entity[0] == '#') { try { // The # syntax can be in decimal or hex, e.g. // å --> decimal // å --> same char in hex // See http://www.w3.org/TR/REC-html40/charset.html#entities if (entity[1] == 'x' || entity[1] == 'X') ch = (char) Int32.Parse(entity.Substring(2), NumberStyles.AllowHexSpecifier); else ch = (char) Int32.Parse(entity.Substring(1)); i = index; // already looked at everything until semicolon } catch (System.FormatException) { i++; //if the number isn't valid, ignore it } catch (System.ArgumentException) { i++; // if there is no number, ignore it. } } else { i = index; // already looked at everything until semicolon char entityChar = HtmlEntities.Lookup(entity); if (entityChar != (char)0) { ch = entityChar; } else { output.Write('&'); output.Write(entity); output.Write(';'); continue; } } } } output.Write(ch); } } /// /// /// HTML encodes a string and returns the encoded string. /// /// public static String HtmlEncode(String s) { if (s == null) return null; int pos = IndexOfHtmlEncodingChars(s, 0); if (pos == -1) return s; StringBuilder builder = new StringBuilder(s.Length + 5); int cch = s.Length; int startPos = 0; for (;;) { if (pos > startPos) { builder.Append(s, startPos, pos - startPos); } char ch = s[pos]; if (ch <= '>') { switch (ch) { case '<': builder.Append("<"); break; case '>': builder.Append(">"); break; case '"': builder.Append("""); break; case '&': builder.Append("&"); break; default: Debug.Assert(false, "Unexpected value for ch, ch=" + ch); break; } } else { #if ENTITY_ENCODE_HIGH_ASCII_CHARS Debug.Assert(ch >= 160 && ch < 256, "ch >= 160 && ch < 256"); // The seemingly arbitrary 160 comes from RFC builder.Append("&#"); builder.Append(((int)ch).ToString(NumberFormatInfo.InvariantInfo)); builder.Append(';'); #else Debug.Assert(false); #endif // ENTITY_ENCODE_HIGH_ASCII_CHARS } startPos = pos + 1; if (startPos >= cch) break; pos = IndexOfHtmlEncodingChars(s, startPos); if (pos == -1) { builder.Append(s, startPos, cch - startPos); break; } } return builder.ToString(); } /// /// /// HTML encodes a string and returns the output to a TextWriter stream of /// output. /// /// public unsafe static void HtmlEncode(String s, TextWriter output) { if (s == null) return; int index = IndexOfHtmlEncodingChars(s, 0); if (index == -1) { output.Write(s); return; } Debug.Assert(0 <= index && index <= s.Length, "0 <= index && index <= s.Length"); int cch = s.Length - index; fixed (char * str = s) { char *pch = str; while (index-- > 0) { output.Write(*pch++); } while (cch-- > 0) { char ch = *pch++; if (ch <= '>') { switch (ch) { case '<': output.Write("<"); break; case '>': output.Write(">"); break; case '"': output.Write("""); break; case '&': output.Write("&"); break; default: output.Write(ch); break; } } #if ENTITY_ENCODE_HIGH_ASCII_CHARS else if (ch >= 160 && ch < 256) { // The seemingly arbitrary 160 comes from RFC output.Write("&#"); output.Write(((int)ch).ToString(NumberFormatInfo.InvariantInfo)); output.Write(';'); } #endif // ENTITY_ENCODE_HIGH_ASCII_CHARS else { output.Write(ch); } } } } static unsafe int IndexOfHtmlEncodingChars(string s, int startPos) { Debug.Assert(0 <= startPos && startPos <= s.Length, "0 <= startPos && startPos <= s.Length"); int cch = s.Length - startPos; fixed (char * str = s) { for (char *pch = &str[startPos]; cch > 0; pch++, cch--) { char ch = *pch; if (ch <= '>') { switch (ch) { case '<': case '>': case '"': case '&': return s.Length - cch; } } #if ENTITY_ENCODE_HIGH_ASCII_CHARS else if (ch >= 160 && ch < 256) { return s.Length - cch; } #endif // ENTITY_ENCODE_HIGH_ASCII_CHARS } } return -1; } /// /// /// Encodes a string to make it a valid HTML attribute and returns the encoded string. /// /// public static String HtmlAttributeEncode(String s) { if (s == null) return null; int pos = IndexOfHtmlAttributeEncodingChars(s, 0); if (pos == -1) return s; StringBuilder builder = new StringBuilder(s.Length + 5); int cch = s.Length; int startPos = 0; for (;;) { if (pos > startPos) { builder.Append(s, startPos, pos - startPos); } char ch = s[pos]; switch (ch) { case '"': builder.Append("""); break; case '&': builder.Append("&"); break; case '<': // Whidbey 32404: The character '<' is not valid in an XML attribute value. // (See the W3C XML rec). builder.Append("<"); break; default: Debug.Assert(false, "Unexpected value for ch, ch=" + ch); break; } startPos = pos + 1; if (startPos >= cch) break; pos = IndexOfHtmlAttributeEncodingChars(s, startPos); if (pos == -1) { builder.Append(s, startPos, cch - startPos); break; } } return builder.ToString(); } internal static void HtmlAttributeEncodeInternal(String s, HttpWriter writer) { int pos = IndexOfHtmlAttributeEncodingChars(s, 0); if (pos == -1) { writer.Write(s); return; } int cch = s.Length; int startPos = 0; for (;;) { if (pos > startPos) { writer.WriteString(s, startPos, pos - startPos); } char ch = s[pos]; switch (ch) { case '"': writer.Write("""); break; case '&': writer.Write("&"); break; case '<': // Whidbey 32404: The character '<' is not valid in an XML attribute value. // (See the W3C XML rec). writer.Write("<"); break; } startPos = pos + 1; if (startPos >= cch) break; pos = IndexOfHtmlAttributeEncodingChars(s, startPos); if (pos == -1) { writer.WriteString(s, startPos, cch - startPos); break; } } } /// /// /// Encodes a string to make it a valid HTML attribute and returns the output /// to a TextWriter stream of /// output. /// /// public unsafe static void HtmlAttributeEncode(String s, TextWriter output) { if (s == null) return; int index = IndexOfHtmlAttributeEncodingChars(s, 0); if (index == -1) { output.Write(s); } else { int cch = s.Length - index; fixed (char * str = s) { char *pch = str; while (index-- > 0) { output.Write(*pch++); } while (cch-- > 0) { char ch = *pch++; if (ch <= '<') { switch (ch) { case '<': output.Write("<"); break; case '"': output.Write("""); break; case '&': output.Write("&"); break; default: output.Write(ch); break; } } else { output.Write(ch); } } } } } static unsafe int IndexOfHtmlAttributeEncodingChars(string s, int startPos) { Debug.Assert(0 <= startPos && startPos <= s.Length, "0 <= startPos && startPos <= s.Length"); int cch = s.Length - startPos; fixed (char * str = s) { for (char *pch = &str[startPos]; cch > 0; pch++, cch--) { char ch = *pch; if (ch <= '<') { switch (ch) { case '<': case '"': case '&': return s.Length - cch; } } } } return -1; } internal static string FormatPlainTextSpacesAsHtml(string s) { if (s == null) { return null; } StringBuilder builder = new StringBuilder(); StringWriter writer = new StringWriter(builder); int cb = s.Length; for (int i = 0; i < cb; i++) { char ch = s[i]; if(ch == ' ') { writer.Write(" "); } else { writer.Write(ch); } } return builder.ToString(); } internal static String FormatPlainTextAsHtml(String s) { if (s == null) return null; StringBuilder builder = new StringBuilder(); StringWriter writer = new StringWriter(builder); FormatPlainTextAsHtml(s, writer); return builder.ToString(); } internal static void FormatPlainTextAsHtml(String s, TextWriter output) { if (s == null) return; int cb = s.Length; char prevCh = '\0'; for (int i=0; i': output.Write(">"); break; case '"': output.Write("""); break; case '&': output.Write("&"); break; case ' ': if (prevCh == ' ') output.Write(" "); else output.Write(ch); break; case '\r': // Ignore \r, only handle \n break; case '\n': output.Write("
"); break; // default: #if ENTITY_ENCODE_HIGH_ASCII_CHARS // The seemingly arbitrary 160 comes from RFC if (ch >= 160 && ch < 256) { output.Write("&#"); output.Write(((int)ch).ToString(NumberFormatInfo.InvariantInfo)); output.Write(';'); break; } #endif // ENTITY_ENCODE_HIGH_ASCII_CHARS output.Write(ch); break; } prevCh = ch; } } ////////////////////////////////////////////////////////////////////////// // // ASII encode - everything all non-7-bit to '?' // /*internal static String AsciiEncode(String s) { if (s == null) return null; StringBuilder sb = new StringBuilder(s.Length); for (int i = 0; i < s.Length; i++) { char ch = s[i]; if (((ch & 0xff80) != 0) || (ch < ' ' && ch != '\r' && ch != '\n' && ch != '\t')) ch = '?'; sb.Append(ch); } return sb.ToString(); }*/ // // Query string parsing support // public static NameValueCollection ParseQueryString(string query) { return ParseQueryString(query, Encoding.UTF8); } public static NameValueCollection ParseQueryString(string query, Encoding encoding) { if (query == null) { throw new ArgumentNullException("query"); } if (encoding == null) { throw new ArgumentNullException("encoding"); } if (query.Length > 0 && query[0] == '?') { query = query.Substring(1); } return new HttpValueCollection(query, false, true, encoding); } ////////////////////////////////////////////////////////////////////////// // // URL decoding / encoding // ////////////////////////////////////////////////////////////////////////// // // Public static methods // /// /// [To be supplied.] /// public static string UrlEncode(string str) { if (str == null) return null; return UrlEncode(str, Encoding.UTF8); } /// /// /// URL encodes a path portion of a URL string and returns the encoded string. /// /// public static string UrlPathEncode(string str) { if (str == null) return null; // recurse in case there is a query string int i = str.IndexOf('?'); if (i >= 0) return UrlPathEncode(str.Substring(0, i)) + str.Substring(i); // encode DBCS characters and spaces only return UrlEncodeSpaces(UrlEncodeNonAscii(str, Encoding.UTF8)); } internal static string AspCompatUrlEncode(string s) { s = UrlEncode(s); s = s.Replace("!", "%21"); s = s.Replace("*", "%2A"); s = s.Replace("(", "%28"); s = s.Replace(")", "%29"); s = s.Replace("-", "%2D"); s = s.Replace(".", "%2E"); s = s.Replace("_", "%5F"); s = s.Replace("\\", "%5C"); return s; } /// /// [To be supplied.] /// public static string UrlEncode(string str, Encoding e) { if (str == null) return null; return Encoding.ASCII.GetString(UrlEncodeToBytes(str, e)); } // Helper to encode the non-ASCII url characters only internal static String UrlEncodeNonAscii(string str, Encoding e) { if (String.IsNullOrEmpty(str)) return str; if (e == null) e = Encoding.UTF8; byte[] bytes = e.GetBytes(str); bytes = UrlEncodeBytesToBytesInternalNonAscii(bytes, 0, bytes.Length, false); return Encoding.ASCII.GetString(bytes); } // Helper to encode spaces only internal static String UrlEncodeSpaces(string str) { if (str != null && str.IndexOf(' ') >= 0) str = str.Replace(" ", "%20"); return str; } /// /// [To be supplied.] /// public static string UrlEncode(byte[] bytes) { if (bytes == null) return null; return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes)); } /// /// [To be supplied.] /// public static string UrlEncode(byte[] bytes, int offset, int count) { if (bytes == null) return null; return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, offset, count)); } /// /// [To be supplied.] /// public static byte[] UrlEncodeToBytes(string str) { if (str == null) return null; return UrlEncodeToBytes(str, Encoding.UTF8); } /// /// [To be supplied.] /// public static byte[] UrlEncodeToBytes(string str, Encoding e) { if (str == null) return null; byte[] bytes = e.GetBytes(str); return UrlEncodeBytesToBytesInternal(bytes, 0, bytes.Length, false); } /// /// [To be supplied.] /// public static byte[] UrlEncodeToBytes(byte[] bytes) { if (bytes == null) return null; return UrlEncodeToBytes(bytes, 0, bytes.Length); } /// /// [To be supplied.] /// public static byte[] UrlEncodeToBytes(byte[] bytes, int offset, int count) { if (bytes == null && count == 0) return null; if (bytes == null) { throw new ArgumentNullException("bytes"); } if (offset < 0 || offset > bytes.Length) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || offset+count > bytes.Length) { throw new ArgumentOutOfRangeException("count"); } return UrlEncodeBytesToBytesInternal(bytes, offset, count, true); } /// /// [To be supplied.] /// public static string UrlEncodeUnicode(string str) { if (str == null) return null; return UrlEncodeUnicodeStringToStringInternal(str, false); } /// /// [To be supplied.] /// public static byte[] UrlEncodeUnicodeToBytes(string str) { if (str == null) return null; return Encoding.ASCII.GetBytes(UrlEncodeUnicode(str)); } /// /// [To be supplied.] /// public static string UrlDecode(string str) { if (str == null) return null; return UrlDecode(str, Encoding.UTF8); } /// /// [To be supplied.] /// public static string UrlDecode(string str, Encoding e) { if (str == null) return null; return UrlDecodeStringFromStringInternal(str, e); } /// /// [To be supplied.] /// public static string UrlDecode(byte[] bytes, Encoding e) { if (bytes == null) return null; return UrlDecode(bytes, 0, bytes.Length, e); } /// /// [To be supplied.] /// public static string UrlDecode(byte[] bytes, int offset, int count, Encoding e) { if (bytes == null && count == 0) return null; if (bytes == null) { throw new ArgumentNullException("bytes"); } if (offset < 0 || offset > bytes.Length) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || offset+count > bytes.Length) { throw new ArgumentOutOfRangeException("count"); } return UrlDecodeStringFromBytesInternal(bytes, offset, count, e); } /// /// [To be supplied.] /// public static byte[] UrlDecodeToBytes(string str) { if (str == null) return null; return UrlDecodeToBytes(str, Encoding.UTF8); } /// /// [To be supplied.] /// public static byte[] UrlDecodeToBytes(string str, Encoding e) { if (str == null) return null; return UrlDecodeToBytes(e.GetBytes(str)); } /// /// [To be supplied.] /// public static byte[] UrlDecodeToBytes(byte[] bytes) { if (bytes == null) return null; return UrlDecodeToBytes(bytes, 0, (bytes != null) ? bytes.Length : 0); } /// /// [To be supplied.] /// public static byte[] UrlDecodeToBytes(byte[] bytes, int offset, int count) { if (bytes == null && count == 0) return null; if (bytes == null) { throw new ArgumentNullException("bytes"); } if (offset < 0 || offset > bytes.Length) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || offset+count > bytes.Length) { throw new ArgumentOutOfRangeException("count"); } return UrlDecodeBytesFromBytesInternal(bytes, offset, count); } // // Implementation for encoding // private static byte[] UrlEncodeBytesToBytesInternal(byte[] bytes, int offset, int count, bool alwaysCreateReturnValue) { int cSpaces = 0; int cUnsafe = 0; // count them first for (int i = 0; i < count; i++) { char ch = (char)bytes[offset+i]; if (ch == ' ') cSpaces++; else if (!IsSafe(ch)) cUnsafe++; } // nothing to expand? if (!alwaysCreateReturnValue && cSpaces == 0 && cUnsafe == 0) return bytes; // expand not 'safe' characters into %XX, spaces to +s byte[] expandedBytes = new byte[count + cUnsafe*2]; int pos = 0; for (int i = 0; i < count; i++) { byte b = bytes[offset+i]; char ch = (char)b; if (IsSafe(ch)) { expandedBytes[pos++] = b; } else if (ch == ' ') { expandedBytes[pos++] = (byte)'+'; } else { expandedBytes[pos++] = (byte)'%'; expandedBytes[pos++] = (byte)IntToHex((b >> 4) & 0xf); expandedBytes[pos++] = (byte)IntToHex(b & 0x0f); } } return expandedBytes; } private static bool IsNonAsciiByte(byte b) { return ( b >= 0x7F || b < 0x20 ); } private static byte[] UrlEncodeBytesToBytesInternalNonAscii(byte[] bytes, int offset, int count, bool alwaysCreateReturnValue) { int cNonAscii = 0; // count them first for (int i = 0; i < count; i++) { if ( IsNonAsciiByte(bytes[offset+i]) ) cNonAscii++; } // nothing to expand? if (!alwaysCreateReturnValue && cNonAscii == 0) return bytes; // expand not 'safe' characters into %XX, spaces to +s byte[] expandedBytes = new byte[count + cNonAscii*2]; int pos = 0; for (int i = 0; i < count; i++) { byte b = bytes[offset+i]; if (IsNonAsciiByte(b)) { expandedBytes[pos++] = (byte)'%'; expandedBytes[pos++] = (byte)IntToHex((b >> 4) & 0xf); expandedBytes[pos++] = (byte)IntToHex(b & 0x0f); } else { expandedBytes[pos++] = b; } } return expandedBytes; } private static string UrlEncodeUnicodeStringToStringInternal(string s, bool ignoreAscii) { int l = s.Length; StringBuilder sb = new StringBuilder(l); for (int i = 0; i < l; i++) { char ch = s[i]; if ((ch & 0xff80) == 0) { // 7 bit? if (ignoreAscii || IsSafe(ch)) { sb.Append(ch); } else if (ch == ' ') { sb.Append('+'); } else { sb.Append('%'); sb.Append(IntToHex((ch >> 4) & 0xf)); sb.Append(IntToHex((ch ) & 0xf)); } } else { // arbitrary Unicode? sb.Append("%u"); sb.Append(IntToHex((ch >> 12) & 0xf)); sb.Append(IntToHex((ch >> 8) & 0xf)); sb.Append(IntToHex((ch >> 4) & 0xf)); sb.Append(IntToHex((ch ) & 0xf)); } } return sb.ToString(); } // // Implementation for decoding // // Internal class to facilitate URL decoding -- keeps char buffer and byte buffer, allows appending of either chars or bytes private class UrlDecoder { private int _bufferSize; // Accumulate characters in a special array private int _numChars; private char[] _charBuffer; // Accumulate bytes for decoding into characters in a special array private int _numBytes; private byte[] _byteBuffer; // Encoding to convert chars to bytes private Encoding _encoding; private void FlushBytes() { if (_numBytes > 0) { _numChars += _encoding.GetChars(_byteBuffer, 0, _numBytes, _charBuffer, _numChars); _numBytes = 0; } } internal UrlDecoder(int bufferSize, Encoding encoding) { _bufferSize = bufferSize; _encoding = encoding; _charBuffer = new char[bufferSize]; // byte buffer created on demand } internal void AddChar(char ch) { if (_numBytes > 0) FlushBytes(); _charBuffer[_numChars++] = ch; } internal void AddByte(byte b) { // if there are no pending bytes treat 7 bit bytes as characters // this optimization is temp disable as it doesn't work for some encodings /* if (_numBytes == 0 && ((b & 0x80) == 0)) { AddChar((char)b); } else */ { if (_byteBuffer == null) _byteBuffer = new byte[_bufferSize]; _byteBuffer[_numBytes++] = b; } } internal String GetString() { if (_numBytes > 0) FlushBytes(); if (_numChars > 0) return new String(_charBuffer, 0, _numChars); else return String.Empty; } } internal static string CollapsePercentUFromStringInternal(string s, Encoding e) { int count = s.Length; UrlDecoder helper = new UrlDecoder(count, e); // go thorugh the string's chars collapsing just %uXXXX and // appending each char as char int loc = s.IndexOf("%u", StringComparison.Ordinal); if(loc == -1) { return s; } for (int pos = 0; pos < count; pos++) { char ch = s[pos]; if (ch == '%' && pos < count-5) { if(s[pos+1] == 'u') { int h1 = HexToInt(s[pos+2]); int h2 = HexToInt(s[pos+3]); int h3 = HexToInt(s[pos+4]); int h4 = HexToInt(s[pos+5]); if (h1 >= 0 && h2 >= 0 && h3 >= 0 && h4 >= 0) { //valid 4 hex chars ch = (char)((h1 << 12) | (h2 << 8) | (h3 << 4) | h4); pos += 5; // add as char helper.AddChar(ch); continue; } } } if ((ch & 0xFF80) == 0) helper.AddByte((byte)ch); // 7 bit have to go as bytes because of Unicode else helper.AddChar(ch); } return helper.GetString(); } private static string UrlDecodeStringFromStringInternal(string s, Encoding e) { int count = s.Length; UrlDecoder helper = new UrlDecoder(count, e); // go through the string's chars collapsing %XX and %uXXXX and // appending each char as char, with exception of %XX constructs // that are appended as bytes for (int pos = 0; pos < count; pos++) { char ch = s[pos]; if (ch == '+') { ch = ' '; } else if (ch == '%' && pos < count-2) { if (s[pos+1] == 'u' && pos < count-5) { int h1 = HexToInt(s[pos+2]); int h2 = HexToInt(s[pos+3]); int h3 = HexToInt(s[pos+4]); int h4 = HexToInt(s[pos+5]); if (h1 >= 0 && h2 >= 0 && h3 >= 0 && h4 >= 0) { // valid 4 hex chars ch = (char)((h1 << 12) | (h2 << 8) | (h3 << 4) | h4); pos += 5; // only add as char helper.AddChar(ch); continue; } } else { int h1 = HexToInt(s[pos+1]); int h2 = HexToInt(s[pos+2]); if (h1 >= 0 && h2 >= 0) { // valid 2 hex chars byte b = (byte)((h1 << 4) | h2); pos += 2; // don't add as char helper.AddByte(b); continue; } } } if ((ch & 0xFF80) == 0) helper.AddByte((byte)ch); // 7 bit have to go as bytes because of Unicode else helper.AddChar(ch); } return helper.GetString(); } private static string UrlDecodeStringFromBytesInternal(byte[] buf, int offset, int count, Encoding e) { UrlDecoder helper = new UrlDecoder(count, e); // go through the bytes collapsing %XX and %uXXXX and appending // each byte as byte, with exception of %uXXXX constructs that // are appended as chars for (int i = 0; i < count; i++) { int pos = offset + i; byte b = buf[pos]; // The code assumes that + and % cannot be in multibyte sequence if (b == '+') { b = (byte)' '; } else if (b == '%' && i < count-2) { if (buf[pos+1] == 'u' && i < count-5) { int h1 = HexToInt((char)buf[pos+2]); int h2 = HexToInt((char)buf[pos+3]); int h3 = HexToInt((char)buf[pos+4]); int h4 = HexToInt((char)buf[pos+5]); if (h1 >= 0 && h2 >= 0 && h3 >= 0 && h4 >= 0) { // valid 4 hex chars char ch = (char)((h1 << 12) | (h2 << 8) | (h3 << 4) | h4); i += 5; // don't add as byte helper.AddChar(ch); continue; } } else { int h1 = HexToInt((char)buf[pos+1]); int h2 = HexToInt((char)buf[pos+2]); if (h1 >= 0 && h2 >= 0) { // valid 2 hex chars b = (byte)((h1 << 4) | h2); i += 2; } } } helper.AddByte(b); } return helper.GetString(); } private static byte[] UrlDecodeBytesFromBytesInternal(byte[] buf, int offset, int count) { int decodedBytesCount = 0; byte[] decodedBytes = new byte[count]; for (int i = 0; i < count; i++) { int pos = offset + i; byte b = buf[pos]; if (b == '+') { b = (byte)' '; } else if (b == '%' && i < count-2) { int h1 = HexToInt((char)buf[pos+1]); int h2 = HexToInt((char)buf[pos+2]); if (h1 >= 0 && h2 >= 0) { // valid 2 hex chars b = (byte)((h1 << 4) | h2); i += 2; } } decodedBytes[decodedBytesCount++] = b; } if (decodedBytesCount < decodedBytes.Length) { byte[] newDecodedBytes = new byte[decodedBytesCount]; Array.Copy(decodedBytes, newDecodedBytes, decodedBytesCount); decodedBytes = newDecodedBytes; } return decodedBytes; } // // Private helpers for URL encoding/decoding // private static int HexToInt(char h) { return( h >= '0' && h <= '9' ) ? h - '0' : ( h >= 'a' && h <= 'f' ) ? h - 'a' + 10 : ( h >= 'A' && h <= 'F' ) ? h - 'A' + 10 : -1; } internal static char IntToHex(int n) { Debug.Assert(n < 0x10); if (n <= 9) return(char)(n + (int)'0'); else return(char)(n - 10 + (int)'a'); } // Set of safe chars, from RFC 1738.4 minus '+' internal static bool IsSafe(char ch) { if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9') return true; switch (ch) { case '-': case '_': case '.': case '!': case '*': case '\'': case '(': case ')': return true; } return false; } ////////////////////////////////////////////////////////////////////////// // // Misc helpers // ////////////////////////////////////////////////////////////////////////// internal static String FormatHttpDateTime(DateTime dt) { if (dt < DateTime.MaxValue.AddDays(-1) && dt > DateTime.MinValue.AddDays(1)) dt = dt.ToUniversalTime(); return dt.ToString("R", DateTimeFormatInfo.InvariantInfo); } internal static String FormatHttpDateTimeUtc(DateTime dt) { return dt.ToString("R", DateTimeFormatInfo.InvariantInfo); } internal static String FormatHttpCookieDateTime(DateTime dt) { if (dt < DateTime.MaxValue.AddDays(-1) && dt > DateTime.MinValue.AddDays(1)) dt = dt.ToUniversalTime(); return dt.ToString("ddd, dd-MMM-yyyy HH':'mm':'ss 'GMT'", DateTimeFormatInfo.InvariantInfo); } } // helper class for lookup of HTML encoding entities internal class HtmlEntities { private static object _lookupLockObject = new object(); // The list is from http://www.w3.org/TR/REC-html40/sgml/entities.html private static String[] _entitiesList = new String[] { "\x0022-quot", "\x0026-amp", "\x003c-lt", "\x003e-gt", "\x00a0-nbsp", "\x00a1-iexcl", "\x00a2-cent", "\x00a3-pound", "\x00a4-curren", "\x00a5-yen", "\x00a6-brvbar", "\x00a7-sect", "\x00a8-uml", "\x00a9-copy", "\x00aa-ordf", "\x00ab-laquo", "\x00ac-not", "\x00ad-shy", "\x00ae-reg", "\x00af-macr", "\x00b0-deg", "\x00b1-plusmn", "\x00b2-sup2", "\x00b3-sup3", "\x00b4-acute", "\x00b5-micro", "\x00b6-para", "\x00b7-middot", "\x00b8-cedil", "\x00b9-sup1", "\x00ba-ordm", "\x00bb-raquo", "\x00bc-frac14", "\x00bd-frac12", "\x00be-frac34", "\x00bf-iquest", "\x00c0-Agrave", "\x00c1-Aacute", "\x00c2-Acirc", "\x00c3-Atilde", "\x00c4-Auml", "\x00c5-Aring", "\x00c6-AElig", "\x00c7-Ccedil", "\x00c8-Egrave", "\x00c9-Eacute", "\x00ca-Ecirc", "\x00cb-Euml", "\x00cc-Igrave", "\x00cd-Iacute", "\x00ce-Icirc", "\x00cf-Iuml", "\x00d0-ETH", "\x00d1-Ntilde", "\x00d2-Ograve", "\x00d3-Oacute", "\x00d4-Ocirc", "\x00d5-Otilde", "\x00d6-Ouml", "\x00d7-times", "\x00d8-Oslash", "\x00d9-Ugrave", "\x00da-Uacute", "\x00db-Ucirc", "\x00dc-Uuml", "\x00dd-Yacute", "\x00de-THORN", "\x00df-szlig", "\x00e0-agrave", "\x00e1-aacute", "\x00e2-acirc", "\x00e3-atilde", "\x00e4-auml", "\x00e5-aring", "\x00e6-aelig", "\x00e7-ccedil", "\x00e8-egrave", "\x00e9-eacute", "\x00ea-ecirc", "\x00eb-euml", "\x00ec-igrave", "\x00ed-iacute", "\x00ee-icirc", "\x00ef-iuml", "\x00f0-eth", "\x00f1-ntilde", "\x00f2-ograve", "\x00f3-oacute", "\x00f4-ocirc", "\x00f5-otilde", "\x00f6-ouml", "\x00f7-divide", "\x00f8-oslash", "\x00f9-ugrave", "\x00fa-uacute", "\x00fb-ucirc", "\x00fc-uuml", "\x00fd-yacute", "\x00fe-thorn", "\x00ff-yuml", "\x0152-OElig", "\x0153-oelig", "\x0160-Scaron", "\x0161-scaron", "\x0178-Yuml", "\x0192-fnof", "\x02c6-circ", "\x02dc-tilde", "\x0391-Alpha", "\x0392-Beta", "\x0393-Gamma", "\x0394-Delta", "\x0395-Epsilon", "\x0396-Zeta", "\x0397-Eta", "\x0398-Theta", "\x0399-Iota", "\x039a-Kappa", "\x039b-Lambda", "\x039c-Mu", "\x039d-Nu", "\x039e-Xi", "\x039f-Omicron", "\x03a0-Pi", "\x03a1-Rho", "\x03a3-Sigma", "\x03a4-Tau", "\x03a5-Upsilon", "\x03a6-Phi", "\x03a7-Chi", "\x03a8-Psi", "\x03a9-Omega", "\x03b1-alpha", "\x03b2-beta", "\x03b3-gamma", "\x03b4-delta", "\x03b5-epsilon", "\x03b6-zeta", "\x03b7-eta", "\x03b8-theta", "\x03b9-iota", "\x03ba-kappa", "\x03bb-lambda", "\x03bc-mu", "\x03bd-nu", "\x03be-xi", "\x03bf-omicron", "\x03c0-pi", "\x03c1-rho", "\x03c2-sigmaf", "\x03c3-sigma", "\x03c4-tau", "\x03c5-upsilon", "\x03c6-phi", "\x03c7-chi", "\x03c8-psi", "\x03c9-omega", "\x03d1-thetasym", "\x03d2-upsih", "\x03d6-piv", "\x2002-ensp", "\x2003-emsp", "\x2009-thinsp", "\x200c-zwnj", "\x200d-zwj", "\x200e-lrm", "\x200f-rlm", "\x2013-ndash", "\x2014-mdash", "\x2018-lsquo", "\x2019-rsquo", "\x201a-sbquo", "\x201c-ldquo", "\x201d-rdquo", "\x201e-bdquo", "\x2020-dagger", "\x2021-Dagger", "\x2022-bull", "\x2026-hellip", "\x2030-permil", "\x2032-prime", "\x2033-Prime", "\x2039-lsaquo", "\x203a-rsaquo", "\x203e-oline", "\x2044-frasl", "\x20ac-euro", "\x2111-image", "\x2118-weierp", "\x211c-real", "\x2122-trade", "\x2135-alefsym", "\x2190-larr", "\x2191-uarr", "\x2192-rarr", "\x2193-darr", "\x2194-harr", "\x21b5-crarr", "\x21d0-lArr", "\x21d1-uArr", "\x21d2-rArr", "\x21d3-dArr", "\x21d4-hArr", "\x2200-forall", "\x2202-part", "\x2203-exist", "\x2205-empty", "\x2207-nabla", "\x2208-isin", "\x2209-notin", "\x220b-ni", "\x220f-prod", "\x2211-sum", "\x2212-minus", "\x2217-lowast", "\x221a-radic", "\x221d-prop", "\x221e-infin", "\x2220-ang", "\x2227-and", "\x2228-or", "\x2229-cap", "\x222a-cup", "\x222b-int", "\x2234-there4", "\x223c-sim", "\x2245-cong", "\x2248-asymp", "\x2260-ne", "\x2261-equiv", "\x2264-le", "\x2265-ge", "\x2282-sub", "\x2283-sup", "\x2284-nsub", "\x2286-sube", "\x2287-supe", "\x2295-oplus", "\x2297-otimes", "\x22a5-perp", "\x22c5-sdot", "\x2308-lceil", "\x2309-rceil", "\x230a-lfloor", "\x230b-rfloor", "\x2329-lang", "\x232a-rang", "\x25ca-loz", "\x2660-spades", "\x2663-clubs", "\x2665-hearts", "\x2666-diams", }; private static Hashtable _entitiesLookupTable; private HtmlEntities() { } internal /*public*/ static char Lookup(String entity) { if (_entitiesLookupTable == null) { // populate hashtable on demand lock (_lookupLockObject) { if (_entitiesLookupTable == null) { Hashtable t = new Hashtable(); foreach (String s in _entitiesList) t[s.Substring(2)] = s[0]; // 1st char is the code, 2nd '-' _entitiesLookupTable = t; } } } Object obj = _entitiesLookupTable[entity]; if (obj != null) return (char)obj; else return (char)0; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK