Web服务器(CassiniDev的裁减版)

 做此程序的原因是将软件部署简化,省去IIS的麻烦部署,减少项目实施人员的工作量和工作复杂度

 

Server sv = new Server(8000, "/", @"D:\web", IPAddress.Any, null, "Login.aspx");
//  **********************************************************************************

//  CassiniDev - http://cassinidev.codeplex.com

// 

//  Copyright (c) 2010 Sky Sanders. All rights reserved.

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

//  

//  This source code is subject to terms and conditions of the Microsoft Public

//  License (Ms-PL). A copy of the license can be found in the license.txt file

//  included in this distribution.

//  

//  You must not remove this notice, or any other, from this software.

//  

//  **********************************************************************************



#region



using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Globalization;

using System.IO;

using System.Net;

using System.Net.Sockets;

using System.Reflection;

using System.Runtime.Remoting;

using System.Security.Permissions;

using System.Security.Principal;

using System.Text;

using System.Threading;

using System.Web;

using System.Web.Hosting;





#endregion



namespace SimpleWebServer

{

    ///<summary>

    ///</summary>

    [PermissionSet(SecurityAction.LinkDemand, Name = "Everything"),

     PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]

    public class Server : MarshalByRefObject, IDisposable

    {

        ///<summary>

        ///</summary>

        public List<string> Plugins = new List<string>();

        ///<summary>

        ///</summary>

        public readonly ApplicationManager ApplicationManager;



        private readonly bool _disableDirectoryListing;



        private readonly string _hostName;



        private readonly IPAddress _ipAddress;



        private readonly object _lockObject;



        private readonly string _physicalPath;



        private readonly int _port;

        private readonly bool _requireAuthentication;

        //private readonly int _timeoutInterval;

        private readonly string _virtualPath;

        private bool _disposed;



        private Host _host;



        private IntPtr _processToken;



        private string _processUser;



        //private int _requestCount;



        private bool _shutdownInProgress;



        private Socket _socket;



        //private Timer _timer;



        private string _appId;



        private string _dfPage;

        ///<summary>

        ///</summary>

        public string AppId

        {

            get { return _appId; }

        }

        ///<summary>

        ///</summary>

        public AppDomain HostAppDomain

        {

            get

            {

                if (_host == null)

                {

                    GetHost();

                }

                if (_host != null)

                {

                    return _host.AppDomain;

                }

                return null;

            }

        }





        ///<summary>

        ///</summary>

        ///<param name="port"></param>

        ///<param name="virtualPath"></param>

        ///<param name="physicalPath"></param>

        public Server(int port, string virtualPath, string physicalPath)

            : this(port, virtualPath, physicalPath, false, false)

        {

        }



        ///<summary>

        ///</summary>

        ///<param name="port"></param>

        ///<param name="physicalPath"></param>

        public Server(int port, string physicalPath)

            : this(port, "/", physicalPath, IPAddress.Loopback)

        {

        }



        ///<summary>

        ///</summary>

        ///<param name="port"></param>

        ///<param name="virtualPath"></param>

        ///<param name="physicalPath"></param>

        ///<param name="ipAddress"></param>

        ///<param name="hostName"></param>

        ///<param name="requireAuthentication"></param>

        public Server(int port, string virtualPath, string physicalPath, IPAddress ipAddress, string hostName)

            : this(port, virtualPath, physicalPath, ipAddress, hostName,false, false, null)

        {

        }



        ///<summary>

        ///</summary>

        ///<param name="port"></param>

        ///<param name="virtualPath"></param>

        ///<param name="physicalPath"></param>

        ///<param name="requireAuthentication"></param>

        public Server(int port, string virtualPath, string physicalPath, bool requireAuthentication)

            : this(port, virtualPath, physicalPath, requireAuthentication, false)

        {

        }



        ///<summary>

        ///</summary>

        ///<param name="port"></param>

        ///<param name="virtualPath"></param>

        ///<param name="physicalPath"></param>

        ///<param name="ipAddress"></param>

        ///<param name="hostName"></param>

        public Server(int port, string virtualPath, string physicalPath, IPAddress ipAddress, string hostName,string dfPage)

            : this(port, virtualPath, physicalPath, ipAddress, hostName, false, false, dfPage)

        {

        }



        ///<summary>

        ///</summary>

        ///<param name="port"></param>

        ///<param name="virtualPath"></param>

        ///<param name="physicalPath"></param>

        ///<param name="ipAddress"></param>

        ///<param name="hostName"></param>

        ///<param name="requireAuthentication"></param>

        ///<param name="disableDirectoryListing"></param>

        public Server(int port, string virtualPath, string physicalPath, IPAddress ipAddress, string hostName,

                      bool requireAuthentication, bool disableDirectoryListing, string dfPage)

            : this(port, virtualPath, physicalPath, requireAuthentication, disableDirectoryListing)

        {

            _ipAddress = ipAddress;

            _hostName = hostName;

            if (!String.IsNullOrEmpty(dfPage))

                dfPage.TrimStart('/');

            _dfPage = "/" + dfPage;

            //_timeoutInterval = timeout;

        }



        ///<summary>

        ///</summary>

        ///<param name="port"></param>

        ///<param name="virtualPath"></param>

        ///<param name="physicalPath"></param>

        ///<param name="ipAddress"></param>

        public Server(int port, string virtualPath, string physicalPath, IPAddress ipAddress)

            : this(port, virtualPath, physicalPath, ipAddress, null, false, false , null)

        {

        }



        ///<summary>

        ///</summary>

        ///<param name="port"></param>

        ///<param name="virtualPath"></param>

        ///<param name="physicalPath"></param>

        ///<param name="requireAuthentication"></param>

        ///<param name="disableDirectoryListing"></param>

        public Server(int port, string virtualPath, string physicalPath, bool requireAuthentication,

                      bool disableDirectoryListing)

        {

            try

            {

                Assembly.ReflectionOnlyLoad("Common.Logging");

            }

            // ReSharper disable EmptyGeneralCatchClause

            catch

            // ReSharper restore EmptyGeneralCatchClause

            {

            }

            _ipAddress = IPAddress.Loopback;

            _requireAuthentication = requireAuthentication;

            _disableDirectoryListing = disableDirectoryListing;

            _lockObject = new object();

            _port = port;

            _virtualPath = virtualPath;

            _physicalPath = Path.GetFullPath(physicalPath);

            _physicalPath = _physicalPath.EndsWith("\\", StringComparison.Ordinal)

                                ? _physicalPath

                                : _physicalPath + "\\";



            ApplicationManager = ApplicationManager.GetApplicationManager();

            string uniqueAppString = string.Concat(virtualPath, physicalPath,":",_port.ToString()).ToLowerInvariant();

            _appId = (uniqueAppString.GetHashCode()).ToString("x", CultureInfo.InvariantCulture);

            ObtainProcessToken();

        }



     



        



        ///<summary>

        ///</summary>

        public bool DisableDirectoryListing

        {

            get { return _disableDirectoryListing; }

        }



        ///<summary>

        ///</summary>

        public bool RequireAuthentication

        {

            get { return _requireAuthentication; }

        }



        /////<summary>

        /////</summary>

        //public int TimeoutInterval

        //{

        //    get { return _timeoutInterval; }

        //}



        ///<summary>

        ///</summary>

        public string HostName

        {

            get { return _hostName; }

        }



        ///<summary>

        ///</summary>

// ReSharper disable InconsistentNaming

        public IPAddress IPAddress

// ReSharper restore InconsistentNaming

        {

            get { return _ipAddress; }

        }



        ///<summary>

        ///</summary>

        public string PhysicalPath

        {

            get { return _physicalPath; }

        }



        ///<summary>

        ///</summary>

        public int Port

        {

            get { return _port; }

        }



        ///<summary>

        ///</summary>

        public string RootUrl

        {

            get

            {

                string hostname = _hostName;

                if (string.IsNullOrEmpty(_hostName))

                {

                    if (_ipAddress.Equals(IPAddress.Loopback) || _ipAddress.Equals(IPAddress.IPv6Loopback) ||

                        _ipAddress.Equals(IPAddress.Any) || _ipAddress.Equals(IPAddress.IPv6Any))

                    {

                        hostname = "localhost";

                    }

                    else

                    {

                        hostname = _ipAddress.ToString();

                    }

                }



                return _port != 80

                           ?

                               String.Format("http://{0}:{1}{2}", hostname, _port, _virtualPath)

                           :

                    //FIX: #12017 - TODO:TEST

                       string.Format("http://{0}{1}", hostname, _virtualPath);

            }

        }



        ///<summary>

        ///</summary>

        public string VirtualPath

        {

            get { return _virtualPath; }

        }



        #region IDisposable Members



        /// <summary>

        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

        /// </summary>

        /// <filterpriority>2</filterpriority>

        public void Dispose()

        {

            if (!_disposed)

            {

                ShutDown();

            }

            _disposed = true;

            GC.SuppressFinalize(this);

        }



        #endregion



        ///<summary>

        ///</summary>

        public event EventHandler<RequestEventArgs> RequestComplete;



        /////<summary>

        /////</summary>

        //public event EventHandler TimedOut;



        ///<summary>

        ///</summary>

        ///<returns></returns>

        public IntPtr GetProcessToken()

        {

            return _processToken;

        }



        ///<summary>

        ///</summary>

        ///<returns></returns>

        public string GetProcessUser()

        {

            return _processUser;

        }



        ///<summary>

        ///</summary>

        public void HostStopped()

        {

            _host = null;

        }



        /// <summary>

        /// Obtains a lifetime service object to control the lifetime policy for this instance.

        /// </summary>

        /// <returns>

        /// An object of type <see cref="T:System.Runtime.Remoting.Lifetime.ILease"/> used to control the lifetime policy for this instance. This is the current lifetime service object for this instance if one exists; otherwise, a new lifetime service object initialized to the value of the <see cref="P:System.Runtime.Remoting.Lifetime.LifetimeServices.LeaseManagerPollTime"/> property.

        /// </returns>

        /// <exception cref="T:System.Security.SecurityException">The immediate caller does not have infrastructure permission. 

        ///                 </exception><filterpriority>2</filterpriority><PermissionSet><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="RemotingConfiguration, Infrastructure"/></PermissionSet>

        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]

        public override object InitializeLifetimeService()

        {

            // never expire the license

            return null;

        }



        // called at the end of request processing

        // to disconnect the remoting proxy for Connection object

        // and allow GC to pick it up

        /// <summary>

        /// </summary>

        /// <param name="conn"></param>

        /// <param name="userName"></param>

        public void OnRequestEnd(Connection conn)

        {

            try

            {

                OnRequestComplete(conn.Id);

            }

            catch

            {

                // swallow - we don't want consumer killing the server

            }

            RemotingServices.Disconnect(conn);

            //DecrementRequestCount();

        }



        ///<summary>

        ///</summary>

        public void Start()

        {

            _socket = CreateSocketBindAndListen(AddressFamily.InterNetwork, _ipAddress, _port);



            //start the timer

            //DecrementRequestCount();



            ThreadPool.QueueUserWorkItem(delegate

                {

                    while (!_shutdownInProgress)

                    {

                        try

                        {

                            Socket acceptedSocket = _socket.Accept();



                            ThreadPool.QueueUserWorkItem(delegate

                                {

                                    if (!_shutdownInProgress)

                                    {

                                        Connection conn = new Connection(this, acceptedSocket);



                                        if (conn.WaitForRequestBytes() == 0)

                                        {

                                            conn.WriteErrorAndClose(400);

                                            return;

                                        }



                                        Host host = GetHost();



                                        if (host == null)

                                        {

                                            conn.WriteErrorAndClose(500);

                                            return;

                                        }



                                        //IncrementRequestCount();

                                        host.ProcessRequest(conn,_dfPage);

                                    }

                                });

                        }

                        catch

                        {

                            Thread.Sleep(100);

                        }

                    }

                });

        }





        /// <summary>

        /// Allows an <see cref="T:System.Object"/> to attempt to free resources and perform other cleanup operations before the <see cref="T:System.Object"/> is reclaimed by garbage collection.

        /// </summary>

        ~Server()

        {

            Dispose();

        }





        private static Socket CreateSocketBindAndListen(AddressFamily family, IPAddress address, int port)

        {

            Socket socket = new Socket(family, SocketType.Stream, ProtocolType.Tcp);

            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

            socket.Bind(new IPEndPoint(address, port));

            socket.Listen((int)SocketOptionName.MaxConnections);

            return socket;

        }



        /// <summary>

        /// 

        /// </summary>

        /// <param name="virtualPath"></param>

        /// <param name="physicalPath"></param>

        /// <param name="hostType"></param>

        /// <param name="port"></param>

        /// <returns></returns>

        /// <remarks>

        /// This is Dmitry's hack to enable running outside of GAC.

        /// There are some errors being thrown when running in proc

        /// </remarks>

        private object CreateWorkerAppDomainWithHost(string virtualPath, string physicalPath, Type hostType,int port)

        {





            // create BuildManagerHost in the worker app domain

            //ApplicationManager appManager = ApplicationManager.GetApplicationManager();

            Type buildManagerHostType = typeof(HttpRuntime).Assembly.GetType("System.Web.Compilation.BuildManagerHost");

            IRegisteredObject buildManagerHost = ApplicationManager.CreateObject(_appId, buildManagerHostType, virtualPath,

                                                                          physicalPath, false);



            // call BuildManagerHost.RegisterAssembly to make Host type loadable in the worker app domain

            buildManagerHostType.InvokeMember("RegisterAssembly",

                                              BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic,

                                              null,

                                              buildManagerHost,

                                              new object[] { hostType.Assembly.FullName, hostType.Assembly.Location });



            // create Host in the worker app domain

            // FIXME: getting FileLoadException Could not load file or assembly 'WebDev.WebServer20, Version=4.0.1.6, Culture=neutral, PublicKeyToken=f7f6e0b4240c7c27' or one of its dependencies. Failed to grant permission to execute. (Exception from HRESULT: 0x80131418)

            // when running dnoa 3.4 samples - webdev is registering trust somewhere that we are not

            return ApplicationManager.CreateObject(_appId, hostType, virtualPath, physicalPath, false);

        }



        //private void DecrementRequestCount()

        //{

        //    lock (_lockObject)

        //    {

        //        _requestCount--;



        //        if (_requestCount < 1)

        //        {

        //            _requestCount = 0;



        //            if (_timeoutInterval > 0 && _timer == null)

        //            {

        //                _timer = new Timer(TimeOut, null, _timeoutInterval, Timeout.Infinite);

        //            }

        //        }

        //    }

        //}



        private Host GetHost()

        {

            if (_shutdownInProgress)

                return null;

            Host host = _host;

            if (host == null)

            {

#if NET40

                object obj2 = new object();

                bool flag = false;

                try

                {

                    Monitor.Enter(obj2 = _lockObject, ref flag);

                    host = _host;

                    if (host == null)

                    {

                        host = (Host)CreateWorkerAppDomainWithHost(_virtualPath, _physicalPath, typeof(Host),Port);

                        host.Configure(this, _port, _virtualPath, _physicalPath, _requireAuthentication, _disableDirectoryListing);

                        _host = host;

                    }

                }

                finally

                {

                    if (flag)

                    {

                        Monitor.Exit(obj2);

                    }

                }

#else



                lock (_lockObject)

                {

                    host = _host;

                    if (host == null)

                    {

                        host = (Host)CreateWorkerAppDomainWithHost(_virtualPath, _physicalPath, typeof(Host),Port);

                        host.Configure(this, _port, _virtualPath, _physicalPath, _requireAuthentication, _disableDirectoryListing);

                        _host = host;

                    }

                }



#endif

            }



            return host;

        }



        //private void IncrementRequestCount()

        //{



        //    lock (_lockObject)

        //    {

        //        _requestCount++;



        //        if (_timer != null)

        //        {



        //            _timer.Dispose();

        //            _timer = null;

        //        }

        //    }

        //}





        private void ObtainProcessToken()

        {

            if (Interop.ImpersonateSelf(2))

            {

                Interop.OpenThreadToken(Interop.GetCurrentThread(), 0xf01ff, true, ref _processToken);

                Interop.RevertToSelf();

                // ReSharper disable PossibleNullReferenceException

                _processUser = WindowsIdentity.GetCurrent().Name;

                // ReSharper restore PossibleNullReferenceException

            }

        }



        private void OnRequestComplete(Guid id)

        {



            EventHandler<RequestEventArgs> complete = RequestComplete;





            if (complete != null)

            {

                complete(this, new RequestEventArgs(id));

            }

        }





        ///<summary>

        ///</summary>

        public void ShutDown()

        {

            if (_shutdownInProgress)

            {

                return;

            }



            _shutdownInProgress = true;



            try

            {

                if (_socket != null)

                {

                    _socket.Close();

                }

            }

            // ReSharper disable EmptyGeneralCatchClause

            catch

            // ReSharper restore EmptyGeneralCatchClause

            {

                // TODO: why the swallow?

            }

            finally

            {

                _socket = null;

            }



            try

            {

                if (_host != null)

                {

                    _host.Shutdown();

                }



                // the host is going to raise an event that this class uses to null the field.

                // just wait until the field is nulled and continue.



                while (_host != null)

                {

                    new AutoResetEvent(false).WaitOne(100);

                }

            }

            // ReSharper disable EmptyGeneralCatchClause

            catch

            // ReSharper restore EmptyGeneralCatchClause

            {

                // TODO: what am i afraid of here?

            }

  

        }



        //private void TimeOut(object ignored)

        //{

        //    TimeOut();

        //}



        /////<summary>

        /////</summary>

        //public void TimeOut()

        //{

        //    ShutDown();

        //    OnTimeOut();

        //}



        //private void OnTimeOut()

        //{

        //    EventHandler handler = TimedOut;

        //    if (handler != null) handler(this, EventArgs.Empty);

        //}

    }

}
Server类
//  **********************************************************************************

//  CassiniDev - http://cassinidev.codeplex.com

// 

//  Copyright (c) 2010 Sky Sanders. All rights reserved.

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

//  

//  This source code is subject to terms and conditions of the Microsoft Public

//  License (Ms-PL). A copy of the license can be found in the license.txt file

//  included in this distribution.

//  

//  You must not remove this notice, or any other, from this software.

//  

//  **********************************************************************************



#region



using System;

using System.Collections.Generic;

using System.Data;

using System.IO;

using System.Linq;

using System.Reflection;

using System.Runtime.InteropServices;

using System.Text;

using System.Web.UI;



#endregion



namespace SimpleWebServer

{

    internal static class CommonExtensions

    {

        public static string ConvertToHexView(this byte[] value, int numBytesPerRow)

        {

            if (value == null) return null;



            List<string> hexSplit = BitConverter.ToString(value)

                .Replace('-', ' ')

                .Trim()

                .SplitIntoChunks(numBytesPerRow*3)

                .ToList();



            int byteAddress = 0;

            StringBuilder sb = new StringBuilder();



            for (int i = 0; i < hexSplit.Count; i++)

            {

                sb.AppendLine(byteAddress.ToString("X4") + ":\t" + hexSplit[i]);

                byteAddress += numBytesPerRow;

            }



            return sb.ToString();

        }



        /// <summary>

        /// CassiniDev FIX: #12506

        /// </summary>

        /// <param name="fileName"></param>

        /// <returns></returns>

        public static string GetContentType(string fileName)

        {

            if (!File.Exists(fileName))

            {

                return null;

            }



            string contentType;



            FileInfo info = new FileInfo(fileName);

            string extension = info.Extension.ToLowerInvariant();



            #region switch filetype

            switch (extension)

            {

                    //NOTE: these are fallbacks - and should be refined as needed

                    // Only if the request does not already know

                    // the content-type will this switch be hit - meaning that 

                    // served content-types for extensions listed here may not match

                    // as this method may not be polled.



                case ".svgz":

                    contentType = "image/svg+xml";

                    break;



                    // from registry - last resort - verified mappings follow



                case ".3g2":

                    contentType = "video/3gpp2";

                    break;

                case ".3gp":

                    contentType = "video/3gpp";

                    break;

                case ".3gp2":

                    contentType = "video/3gpp2";

                    break;

                case ".3gpp":

                    contentType = "video/3gpp";

                    break;

                case ".adt":

                    contentType = "audio/vnd.dlna.adts";

                    break;

                case ".amr":

                    contentType = "audio/AMR";

                    break;

                case ".addin":

                    contentType = "text/xml";

                    break;

                case ".evr":

                    contentType = "audio/evrc-qcp";

                    break;

                case ".evrc":

                    contentType = "audio/evrc-qcp";

                    break;

                case ".ssisdeploymentmanifest":

                    contentType = "text/xml";

                    break;

                case ".xoml":

                    contentType = "text/plain";

                    break;

                case ".aac":

                    contentType = "audio/aac";

                    break;

                case ".ac3":

                    contentType = "audio/ac3";

                    break;

                case ".accda":

                    contentType = "application/msaccess";

                    break;

                case ".accdb":

                    contentType = "application/msaccess";

                    break;

                case ".accdc":

                    contentType = "application/msaccess";

                    break;

                case ".accde":

                    contentType = "application/msaccess";

                    break;

                case ".accdr":

                    contentType = "application/msaccess";

                    break;

                case ".accdt":

                    contentType = "application/msaccess";

                    break;

                case ".acrobatsecuritysettings":

                    contentType = "application/vnd.adobe.acrobat-security-settings";

                    break;

                case ".ad":

                    contentType = "text/plain";

                    break;

                case ".ade":

                    contentType = "application/msaccess";

                    break;

                case ".adobebridge":

                    contentType = "application/x-bridge-url";

                    break;

                case ".adp":

                    contentType = "application/msaccess";

                    break;

                case ".adts":

                    contentType = "audio/vnd.dlna.adts";

                    break;

                case ".amc":

                    contentType = "application/x-mpeg";

                    break;

                case ".application":

                    contentType = "application/x-ms-application";

                    break;

                case ".asa":

                    contentType = "application/xml";

                    break;

                case ".asax":

                    contentType = "application/xml";

                    break;

                case ".ascx":

                    contentType = "application/xml";

                    break;



                case ".ashx":

                    contentType = "application/xml";

                    break;

                case ".asm":

                    contentType = "text/plain";

                    break;

                case ".asmx":

                    contentType = "application/xml";

                    break;

                case ".aspx":

                    contentType = "application/xml";

                    break;

                case ".awf":

                    contentType = "application/vnd.adobe.workflow";

                    break;

                case ".biz":

                    contentType = "text/xml";

                    break;



                case ".c2r":

                    contentType = "text/vnd-ms.click2record+xml";

                    break;

                case ".caf":

                    contentType = "audio/x-caf";

                    break;



                case ".cc":

                    contentType = "text/plain";

                    break;

                case ".cd":

                    contentType = "text/plain";

                    break;

                case ".cdda":

                    contentType = "audio/aiff";

                    break;



                case ".config":

                    contentType = "application/xml";

                    break;

                case ".contact":

                    contentType = "text/x-ms-contact";

                    break;

                case ".coverage":

                    contentType = "application/xml";

                    break;

                case ".cpp":

                    contentType = "text/plain";

                    break;

                case ".cs":

                    contentType = "text/plain";

                    break;

                case ".csdproj":

                    contentType = "text/plain";

                    break;

                case ".csproj":

                    contentType = "text/plain";

                    break;

                case ".jar":

                    contentType = "application/java-archive";

                    break;

                case ".csv":

                    contentType = "application/vnd.ms-excel";

                    break;

                case ".cur":

                    contentType = "text/plain";

                    break;

                case ".cxx":

                    contentType = "text/plain";

                    break;

                case ".datasource":

                    contentType = "application/xml";

                    break;

                case ".dbproj":

                    contentType = "text/plain";

                    break;

                case ".dcd":

                    contentType = "text/xml";

                    break;

                case ".dd":

                    contentType = "text/plain";

                    break;

                case ".def":

                    contentType = "text/plain";

                    break;



                case ".design":

                    contentType = "image/design";

                    break;

                case ".dgml":

                    contentType = "application/xml";

                    break;

                case ".dib":

                    contentType = "image/bmp";

                    break;

                case ".dif":

                    contentType = "video/x-dv";

                    break;

                case ".docm":

                    contentType = "application/vnd.ms-word.document.macroEnabled.12";

                    break;

                case ".docx":

                    contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";

                    break;

                case ".dotm":

                    contentType = "application/vnd.ms-word.template.macroEnabled.12";

                    break;

                case ".dotx":

                    contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.template";

                    break;

                case ".dsp":

                    contentType = "text/plain";

                    break;

                case ".dsprototype":

                    contentType = "text/plain";

                    break;

                case ".dsw":

                    contentType = "text/plain";

                    break;

                case ".dtd":

                    contentType = "application/xml-dtd";

                    break;

                case ".dtsconfig":

                    contentType = "text/xml";

                    break;

                case ".dv":

                    contentType = "video/x-dv";

                    break;

                case ".dwfx":

                    contentType = "model/vnd.dwfx+xps";

                    break;

                case ".easmx":

                    contentType = "model/vnd.easmx+xps";

                    break;

                case ".edrwx":

                    contentType = "model/vnd.edrwx+xps";

                    break;

                case ".eprtx":

                    contentType = "model/vnd.eprtx+xps";

                    break;

                case ".fdf":

                    contentType = "application/vnd.fdf";

                    break;

                case ".filters":

                    contentType = "Application/xml";

                    break;

                case ".flc":

                    contentType = "video/flc";

                    break;

                case ".fo":

                    contentType = "text/xml";

                    break;

                case ".fsscript":

                    contentType = "application/fsharp-script";

                    break;

                case ".fsx":

                    contentType = "application/fsharp-script";

                    break;

                case ".generictest":

                    contentType = "application/xml";

                    break;

                case ".group":

                    contentType = "text/x-ms-group";

                    break;

                case ".gsm":

                    contentType = "audio/x-gsm";

                    break;

                case ".hpp":

                    contentType = "text/plain";

                    break;

                case ".hxa":

                    contentType = "application/xml";

                    break;

                case ".hxc":

                    contentType = "application/xml";

                    break;

                case ".hxd":

                    contentType = "application/octet-stream";

                    break;

                case ".hxe":

                    contentType = "application/xml";

                    break;

                case ".hxf":

                    contentType = "application/xml";

                    break;

                case ".hxh":

                    contentType = "application/octet-stream";

                    break;

                case ".hxi":

                    contentType = "application/octet-stream";

                    break;

                case ".hxk":

                    contentType = "application/xml";

                    break;

                case ".hxq":

                    contentType = "application/octet-stream";

                    break;

                case ".hxr":

                    contentType = "application/octet-stream";

                    break;

                case ".hxs":

                    contentType = "application/octet-stream";

                    break;

                case ".hxt":

                    contentType = "application/xml";

                    break;

                case ".hxv":

                    contentType = "application/xml";

                    break;

                case ".hxw":

                    contentType = "application/octet-stream";

                    break;

                case ".hxx":

                    contentType = "text/plain";

                    break;

                case ".i":

                    contentType = "text/plain";

                    break;

                case ".idl":

                    contentType = "text/plain";

                    break;

                case ".inc":

                    contentType = "text/plain";

                    break;

                case ".inl":

                    contentType = "text/plain";

                    break;

                case ".ipproj":

                    contentType = "text/plain";

                    break;

                case ".iqy":

                    contentType = "text/x-ms-iqy";

                    break;

                case ".ismv":

                    contentType = "video/ismv";

                    break;

                case ".jsx":

                    contentType = "text/plain";

                    break;

                case ".jsxbin":

                    contentType = "text/plain";

                    break;

                case ".jtx":

                    contentType = "application/x-jtx+xps";

                    break;

                case ".ldd":

                    contentType = "text/plain";

                    break;

                case ".library-ms":

                    contentType = "application/windows-library+xml";

                    break;

                case ".loadtest":

                    contentType = "application/xml";

                    break;

                case ".lsaprototype":

                    contentType = "text/plain";

                    break;

                case ".lst":

                    contentType = "text/plain";

                    break;

                case ".m1v":

                    contentType = "video/mpeg";

                    break;

                case ".m2t":

                    contentType = "video/vnd.dlna.mpeg-tts";

                    break;

                case ".m2ts":

                    contentType = "video/vnd.dlna.mpeg-tts";

                    break;

                case ".m2v":

                    contentType = "video/mpeg";

                    break;

                case ".m4a":

                    contentType = "audio/mp4";

                    break;

                case ".m4b":

                    contentType = "audio/x-m4b";

                    break;

                case ".m4p":

                    contentType = "audio/x-m4p";

                    break;

                case ".m4v":

                    contentType = "video/x-m4v";

                    break;

                case ".mac":

                    contentType = "image/x-macpaint";

                    break;

                case ".mak":

                    contentType = "text/plain";

                    break;

                case ".map":

                    contentType = "text/plain";

                    break;

                case ".master":

                    contentType = "application/xml";

                    break;

                case ".mda":

                    contentType = "application/msaccess";

                    break;

                case ".mde":

                    contentType = "application/msaccess";

                    break;

                case ".mdp":

                    contentType = "text/plain";

                    break;

                case ".mfp":

                    contentType = "application/x-shockwave-flash";

                    break;

                case ".mk":

                    contentType = "text/plain";

                    break;

                case ".mod":

                    contentType = "video/mpeg";

                    break;

                case ".mp2v":

                    contentType = "video/mpeg";

                    break;

                case ".mp4":

                    contentType = "video/mp4";

                    break;

                case ".mp4v":

                    contentType = "video/mp4";

                    break;

                case ".mpf":

                    contentType = "application/vnd.ms-mediapackage";

                    break;

                case ".mqv":

                    contentType = "video/quicktime";

                    break;

                case ".mts":

                    contentType = "video/vnd.dlna.mpeg-tts";

                    break;

                case ".mtx":

                    contentType = "application/xml";

                    break;

                case ".mxp":

                    contentType = "application/x-mmxp";

                    break;

                case ".nix":

                    contentType = "application/x-mix-transfer";

                    break;

                case ".odc":

                    contentType = "text/x-ms-odc";

                    break;

                case ".odh":

                    contentType = "text/plain";

                    break;

                case ".odl":

                    contentType = "text/plain";

                    break;

                case ".odp":

                    contentType = "application/vnd.oasis.opendocument.presentation";

                    break;

                case ".ods":

                    contentType = "application/vnd.oasis.opendocument.spreadsheet";

                    break;

                case ".odt":

                    contentType = "application/vnd.oasis.opendocument.text";

                    break;

                case ".orderedtest":

                    contentType = "application/xml";

                    break;

                case ".osdx":

                    contentType = "application/opensearchdescription+xml";

                    break;

                case ".pct":

                    contentType = "image/pict";

                    break;

                case ".pcx":

                    contentType = "image/x-pcx";

                    break;



                case ".pdfxml":

                    contentType = "application/vnd.adobe.pdfxml";

                    break;

                case ".pdx":

                    contentType = "application/vnd.adobe.pdx";

                    break;

                case ".pic":

                    contentType = "image/pict";

                    break;

                case ".pict":

                    contentType = "image/pict";

                    break;

                case ".pkgdef":

                    contentType = "text/plain";

                    break;

                case ".pkgundef":

                    contentType = "text/plain";

                    break;

                case ".png":

                    contentType = "image/png";

                    break;

                case ".pnt":

                    contentType = "image/x-macpaint";

                    break;

                case ".pntg":

                    contentType = "image/x-macpaint";

                    break;

                case ".potm":

                    contentType = "application/vnd.ms-powerpoint.template.macroEnabled.12";

                    break;

                case ".potx":

                    contentType = "application/vnd.openxmlformats-officedocument.presentationml.template";

                    break;

                case ".ppa":

                    contentType = "application/vnd.ms-powerpoint";

                    break;

                case ".ppam":

                    contentType = "application/vnd.ms-powerpoint.addin.macroEnabled.12";

                    break;

                case ".ppsm":

                    contentType = "application/vnd.ms-powerpoint.slideshow.macroEnabled.12";

                    break;

                case ".ppsx":

                    contentType = "application/vnd.openxmlformats-officedocument.presentationml.slideshow";

                    break;

                case ".pptm":

                    contentType = "application/vnd.ms-powerpoint.presentation.macroEnabled.12";

                    break;

                case ".pptx":

                    contentType = "application/vnd.openxmlformats-officedocument.presentationml.presentation";

                    break;

                case ".psc1":

                    contentType = "application/PowerShell";

                    break;

                case ".psess":

                    contentType = "application/xml";

                    break;

                case ".pwz":

                    contentType = "application/vnd.ms-powerpoint";

                    break;

                case ".pxr":

                    contentType = "image/pxr";

                    break;

                case ".qcp":

                    contentType = "audio/vnd.qcelp";

                    break;

                case ".qht":

                    contentType = "text/x-html-insertion";

                    break;

                case ".qhtm":

                    contentType = "text/x-html-insertion";

                    break;

                case ".qti":

                    contentType = "image/x-quicktime";

                    break;

                case ".qtif":

                    contentType = "image/x-quicktime";

                    break;

                case ".qtl":

                    contentType = "application/x-quicktimeplayer";

                    break;

                case ".rat":

                    contentType = "application/rat-file";

                    break;

                case ".raw":

                    contentType = "application/octet-stream";

                    break;



                case ".rc":

                    contentType = "text/plain";

                    break;

                case ".rc2":

                    contentType = "text/plain";

                    break;

                case ".rct":

                    contentType = "text/plain";

                    break;

                case ".rdf":

                    contentType = "text/xml";

                    break;

                case ".rdlc":

                    contentType = "application/xml";

                    break;

                case ".rels":

                    contentType = "application/vnd.ms-package.relationships+xml";

                    break;

                case ".resx":

                    contentType = "application/xml";

                    break;

                case ".rgs":

                    contentType = "text/plain";

                    break;

                case ".rjt":

                    contentType = "application/vnd.rn-realsystem-rjt";

                    break;

                case ".rm":

                    contentType = "application/vnd.rn-realmedia";

                    break;

                case ".rmf":

                    contentType = "application/vnd.adobe.rmf";

                    break;

                case ".rmj":

                    contentType = "application/vnd.rn-realsystem-rmj";

                    break;

                case ".rmm":

                    contentType = "audio/x-pn-realaudio";

                    break;

                case ".rmp":

                    contentType = "application/vnd.rn-rn_music_package";

                    break;

                case ".rms":

                    contentType = "application/vnd.rn-realaudio-secure";

                    break;

                case ".rmvb":

                    contentType = "application/vnd.rn-realmedia-vbr";

                    break;

                case ".rmx":

                    contentType = "application/vnd.rn-realsystem-rmx";

                    break;

                case ".rnx":

                    contentType = "application/vnd.rn-realplayer";

                    break;

                case ".rp":

                    contentType = "image/vnd.rn-realpix";

                    break;

                case ".rpm":

                    contentType = "audio/x-pn-realaudio-plugin";

                    break;

                case ".rqy":

                    contentType = "text/x-ms-rqy";

                    break;

                case ".rsml":

                    contentType = "application/vnd.rn-rsml";

                    break;

                case ".rt":

                    contentType = "text/vnd.rn-realtext";

                    break;

                case ".rtsp":

                    contentType = "application/x-rtsp";

                    break;

                case ".ruleset":

                    contentType = "application/xml";

                    break;

                case ".rv":

                    contentType = "video/vnd.rn-realvideo";

                    break;

                case ".s":

                    contentType = "text/plain";

                    break;

                case ".sd":

                    contentType = "text/plain";

                    break;

                case ".sd2":

                    contentType = "audio/x-sd2";

                    break;

                case ".sdm":

                    contentType = "text/plain";

                    break;

                case ".sdmdocument":

                    contentType = "text/plain";

                    break;

                case ".sdp":

                    contentType = "application/sdp";

                    break;

                case ".sdv":

                    contentType = "video/sd-video";

                    break;

                case ".searchConnector-ms":

                    contentType = "application/windows-search-connector+xml";

                    break;

                case ".settings":

                    contentType = "application/xml";

                    break;

                case ".sgi":

                    contentType = "image/x-sgi";

                    break;

                case ".shtml":

                    contentType = "text/html";

                    break;

                case ".sitemap":

                    contentType = "application/xml";

                    break;

                case ".skin":

                    contentType = "application/xml";

                    break;

                case ".sldm":

                    contentType = "application/vnd.ms-powerpoint.slide.macroEnabled.12";

                    break;

                case ".sldx":

                    contentType = "application/vnd.openxmlformats-officedocument.presentationml.slide";

                    break;

                case ".slk":

                    contentType = "application/vnd.ms-excel";

                    break;

                case ".sln":

                    contentType = "text/plain";

                    break;

                case ".slupkg-ms":

                    contentType = "application/x-ms-license";

                    break;

                case ".smi":

                    contentType = "application/smil";

                    break;

                case ".smil":

                    contentType = "application/smil";

                    break;

                case ".snippet":

                    contentType = "application/xml";

                    break;

                case ".sol":

                    contentType = "text/plain";

                    break;

                case ".sor":

                    contentType = "text/plain";

                    break;

                case ".srf":

                    contentType = "text/plain";

                    break;

                case ".svc":

                    contentType = "application/xml";

                    break;

                case ".tga":

                    contentType = "image/x-targa";

                    break;

                case ".targa":

                    contentType = "image/x-targa";

                    break;

                case ".testrunconfig":

                    contentType = "application/xml";

                    break;

                case ".testsettings":

                    contentType = "application/xml";

                    break;

                case ".thmx":

                    contentType = "application/vnd.ms-officetheme";

                    break;

                case ".tlh":

                    contentType = "text/plain";

                    break;

                case ".tli":

                    contentType = "text/plain";

                    break;

                case ".trx":

                    contentType = "application/xml";

                    break;

                case ".ts":

                    contentType = "video/vnd.dlna.mpeg-tts";

                    break;

                case ".tts":

                    contentType = "video/vnd.dlna.mpeg-tts";

                    break;

                case ".user":

                    contentType = "text/plain";

                    break;

                case ".vb":

                    contentType = "text/plain";

                    break;

                case ".vbdproj":

                    contentType = "text/plain";

                    break;

                case ".vbproj":

                    contentType = "text/plain";

                    break;

                case ".vcproj":

                    contentType = "Application/xml";

                    break;

                case ".vcxproj":

                    contentType = "Application/xml";

                    break;

                case ".vddproj":

                    contentType = "text/plain";

                    break;

                case ".vdp":

                    contentType = "text/plain";

                    break;

                case ".vdproj":

                    contentType = "text/plain";

                    break;

                case ".vdx":

                    contentType = "application/vnd.visio";

                    break;

                case ".vscontent":

                    contentType = "application/xml";

                    break;

                case ".vsct":

                    contentType = "text/xml";

                    break;

                case ".vsd":

                    contentType = "application/vnd.visio";

                    break;

                case ".vsi":

                    contentType = "application/ms-vsi";

                    break;

                case ".vsix":

                    contentType = "application/vsix";

                    break;

                case ".vsixlangpack":

                    contentType = "text/xml";

                    break;

                case ".vsixmanifest":

                    contentType = "text/xml";

                    break;

                case ".vsl":

                    contentType = "application/vnd.visio";

                    break;

                case ".vsmdi":

                    contentType = "application/xml";

                    break;

                case ".vspscc":

                    contentType = "text/plain";

                    break;

                case ".vss":

                    contentType = "application/vnd.visio";

                    break;

                case ".vsscc":

                    contentType = "text/plain";

                    break;

                case ".vssettings":

                    contentType = "text/xml";

                    break;

                case ".vssscc":

                    contentType = "text/plain";

                    break;

                case ".vst":

                    contentType = "application/vnd.visio";

                    break;

                case ".vstemplate":

                    contentType = "text/xml";

                    break;

                case ".vsto":

                    contentType = "application/x-ms-vsto";

                    break;

                case ".vsu":

                    contentType = "application/vnd.visio";

                    break;

                case ".vsw":

                    contentType = "application/vnd.visio";

                    break;

                case ".vsx":

                    contentType = "application/vnd.visio";

                    break;

                case ".vtx":

                    contentType = "application/vnd.visio";

                    break;

                case ".wax":

                    contentType = "audio/x-ms-wax";

                    break;

                case ".wbk":

                    contentType = "application/msword";

                    break;

                case ".wdp":

                    contentType = "image/vnd.ms-photo";

                    break;

                case ".webtest":

                    contentType = "application/xml";

                    break;

                case ".wiq":

                    contentType = "application/xml";

                    break;

                case ".wiz":

                    contentType = "application/msword";

                    break;

                case ".wm":

                    contentType = "video/x-ms-wm";

                    break;

                case ".wma":

                    contentType = "audio/x-ms-wma";

                    break;

                case ".wmd":

                    contentType = "application/x-ms-wmd";

                    break;

                case ".wmv":

                    contentType = "video/x-ms-wmv";

                    break;

                case ".wmx":

                    contentType = "video/x-ms-wmx";

                    break;

                case ".wmz":

                    contentType = "application/x-ms-wmz";

                    break;

                case ".wpl":

                    contentType = "application/vnd.ms-wpl";

                    break;

                case ".wsc":

                    contentType = "text/scriptlet";

                    break;

                case ".wsdl":

                    contentType = "application/xml";

                    break;

                case ".wvx":

                    contentType = "video/x-ms-wvx";

                    break;

                case ".xaml":

                    contentType = "application/xaml+xml";

                    break;

                case ".xbap":

                    contentType = "application/x-ms-xbap";

                    break;

                case ".xbrl":

                    contentType = "text/xml";

                    break;

                case ".xdp":

                    contentType = "application/vnd.adobe.xdp+xml";

                    break;

                case ".xdr":

                    contentType = "application/xml";

                    break;

                case ".xej":

                    contentType = "application/xej+xml";

                    break;

                case ".xel":

                    contentType = "application/xel+xml";

                    break;

                case ".xesc":

                    contentType = "application/x-ms-wmv";

                    break;

                case ".xfd":

                    contentType = "application/vnd.adobe.xfd+xml";

                    break;

                case ".xfdf":

                    contentType = "application/vnd.adobe.xfdf";

                    break;

                case ".xht":

                    contentType = "application/xhtml+xml";

                    break;

                case ".xhtml":

                    contentType = "application/xhtml+xml";

                    break;

                case ".xlam":

                    contentType = "application/vnd.ms-excel.addin.macroEnabled.12";

                    break;

                case ".xlk":

                    contentType = "application/vnd.ms-excel";

                    break;

                case ".xll":

                    contentType = "application/vnd.ms-excel";

                    break;

                case ".xlsb":

                    contentType = "application/vnd.ms-excel.sheet.binary.macroEnabled.12";

                    break;

                case ".xlsm":

                    contentType = "application/vnd.ms-excel.sheet.macroEnabled.12";

                    break;

                case ".xlsx":

                    contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

                    break;

                case ".xltm":

                    contentType = "application/vnd.ms-excel.template.macroEnabled.12";

                    break;

                case ".xltx":

                    contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.template";

                    break;

                case ".xml":

                    contentType = "application/xml";

                    break;

                case ".xmta":

                    contentType = "application/xml";

                    break;

                case ".xpr":

                    contentType = "image/xpr";

                    break;

                case ".xps":

                    contentType = "application/vnd.ms-xpsdocument";

                    break;

                case ".xrm-ms":

                    contentType = "text/xml";

                    break;

                case ".xsc":

                    contentType = "application/xml";

                    break;

                case ".xsd":

                    contentType = "application/xml";

                    break;

                case ".xsl":

                    contentType = "text/xml";

                    break;

                case ".xslt":

                    contentType = "application/xml";

                    break;

                case ".xss":

                    contentType = "application/xml";

                    break;

                case ".323":

                    contentType = "text/h323";

                    break;

                case ".acx":

                    contentType = "application/internet-property-stream";

                    break;

                case ".ai":

                    contentType = "application/postscript";

                    break;

                case ".aif":

                    contentType = "audio/x-aiff";

                    break;

                case ".aifc":

                    contentType = "audio/x-aiff";

                    break;

                case ".aiff":

                    contentType = "audio/x-aiff";

                    break;

                case ".asf":

                    contentType = "video/x-ms-asf";

                    break;

                case ".asr":

                    contentType = "video/x-ms-asf";

                    break;

                case ".asx":

                    contentType = "video/x-ms-asf";

                    break;

                case ".au":

                    contentType = "audio/basic";

                    break;

                case ".avi":

                    contentType = "video/x-msvideo";

                    break;

                case ".axs":

                    contentType = "application/olescript";

                    break;

                case ".bas":

                    contentType = "text/plain";

                    break;

                case ".bcpio":

                    contentType = "application/x-bcpio";

                    break;

                case ".bin":

                    contentType = "application/octet-stream";

                    break;

                case ".bmp":

                    contentType = "image/bmp";

                    break;

                case ".c":

                    contentType = "text/plain";

                    break;

                case ".cat":

                    contentType = "application/vnd.ms-pkiseccat";

                    break;

                case ".cdf":

                    contentType = "application/x-cdf";

                    break;

                case ".cer":

                    contentType = "application/x-x509-ca-cert";

                    break;

                case ".class":

                    contentType = "application/octet-stream";

                    break;

                case ".clp":

                    contentType = "application/x-msclip";

                    break;

                case ".cmx":

                    contentType = "image/x-cmx";

                    break;

                case ".cod":

                    contentType = "image/cis-cod";

                    break;

                case ".cpio":

                    contentType = "application/x-cpio";

                    break;

                case ".crd":

                    contentType = "application/x-mscardfile";

                    break;

                case ".crl":

                    contentType = "application/pkix-crl";

                    break;

                case ".crt":

                    contentType = "application/x-x509-ca-cert";

                    break;

                case ".csh":

                    contentType = "application/x-csh";

                    break;

                case ".css":

                    contentType = "text/css";

                    break;

                case ".dcr":

                    contentType = "application/x-director";

                    break;

                case ".der":

                    contentType = "application/x-x509-ca-cert";

                    break;

                case ".dir":

                    contentType = "application/x-director";

                    break;

                case ".dll":

                    contentType = "application/x-msdownload";

                    break;

                case ".dms":

                    contentType = "application/octet-stream";

                    break;

                case ".doc":

                    contentType = "application/msword";

                    break;

                case ".dot":

                    contentType = "application/msword";

                    break;

                case ".dvi":

                    contentType = "application/x-dvi";

                    break;

                case ".dxr":

                    contentType = "application/x-director";

                    break;

                case ".eps":

                    contentType = "application/postscript";

                    break;

                case ".etx":

                    contentType = "text/x-setext";

                    break;

                case ".evy":

                    contentType = "application/envoy";

                    break;

                case ".exe":

                    contentType = "application/octet-stream";

                    break;

                case ".fif":

                    contentType = "application/fractals";

                    break;

                case ".flr":

                    contentType = "x-world/x-vrml";

                    break;

                case ".gif":

                    contentType = "image/gif";

                    break;

                case ".gtar":

                    contentType = "application/x-gtar";

                    break;

                case ".gz":

                    contentType = "application/x-gzip";

                    break;

                case ".h":

                    contentType = "text/plain";

                    break;

                case ".hdf":

                    contentType = "application/x-hdf";

                    break;

                case ".hlp":

                    contentType = "application/winhlp";

                    break;

                case ".hqx":

                    contentType = "application/mac-binhex40";

                    break;

                case ".hta":

                    contentType = "application/hta";

                    break;

                case ".htc":

                    contentType = "text/x-component";

                    break;

                case ".htm":

                    contentType = "text/html";

                    break;

                case ".html":

                    contentType = "text/html";

                    break;

                case ".htt":

                    contentType = "text/webviewhtml";

                    break;

                case ".ico":

                    contentType = "image/x-icon";

                    break;

                case ".ief":

                    contentType = "image/ief";

                    break;

                case ".iii":

                    contentType = "application/x-iphone";

                    break;

                case ".ins":

                    contentType = "application/x-internet-signup";

                    break;

                case ".isp":

                    contentType = "application/x-internet-signup";

                    break;

                case ".jfif":

                    contentType = "image/pipeg";

                    break;

                case ".jpe":

                    contentType = "image/jpeg";

                    break;

                case ".jpeg":

                    contentType = "image/jpeg";

                    break;

                case ".jpg":

                    contentType = "image/jpeg";

                    break;

                case ".js":

                    contentType = "application/x-javascript";

                    break;

                case ".latex":

                    contentType = "application/x-latex";

                    break;

                case ".lha":

                    contentType = "application/octet-stream";

                    break;

                case ".lsf":

                    contentType = "video/x-la-asf";

                    break;

                case ".lsx":

                    contentType = "video/x-la-asf";

                    break;

                case ".lzh":

                    contentType = "application/octet-stream";

                    break;

                case ".m13":

                    contentType = "application/x-msmediaview";

                    break;

                case ".m14":

                    contentType = "application/x-msmediaview";

                    break;

                case ".m3u":

                    contentType = "audio/x-mpegurl";

                    break;

                case ".man":

                    contentType = "application/x-troff-man";

                    break;

                case ".mdb":

                    contentType = "application/x-msaccess";

                    break;

                case ".me":

                    contentType = "application/x-troff-me";

                    break;

                case ".mht":

                    contentType = "message/rfc822";

                    break;

                case ".mhtml":

                    contentType = "message/rfc822";

                    break;

                case ".mid":

                    contentType = "audio/mid";

                    break;

                case ".mny":

                    contentType = "application/x-msmoney";

                    break;

                case ".mov":

                    contentType = "video/quicktime";

                    break;

                case ".movie":

                    contentType = "video/x-sgi-movie";

                    break;

                case ".mp2":

                    contentType = "video/mpeg";

                    break;

                case ".mp3":

                    contentType = "audio/mpeg";

                    break;

                case ".mpa":

                    contentType = "video/mpeg";

                    break;

                case ".mpe":

                    contentType = "video/mpeg";

                    break;

                case ".mpeg":

                    contentType = "video/mpeg";

                    break;

                case ".mpg":

                    contentType = "video/mpeg";

                    break;

                case ".mpp":

                    contentType = "application/vnd.ms-project";

                    break;

                case ".mpv2":

                    contentType = "video/mpeg";

                    break;

                case ".ms":

                    contentType = "application/x-troff-ms";

                    break;

                case ".msg":

                    contentType = "application/vnd.ms-outlook";

                    break;

                case ".mvb":

                    contentType = "application/x-msmediaview";

                    break;

                case ".nc":

                    contentType = "application/x-netcdf";

                    break;

                case ".nws":

                    contentType = "message/rfc822";

                    break;

                case ".oda":

                    contentType = "application/oda";

                    break;

                case ".p10":

                    contentType = "application/pkcs10";

                    break;

                case ".p12":

                    contentType = "application/x-pkcs12";

                    break;

                case ".p7b":

                    contentType = "application/x-pkcs7-certificates";

                    break;

                case ".p7c":

                    contentType = "application/x-pkcs7-mime";

                    break;

                case ".p7m":

                    contentType = "application/x-pkcs7-mime";

                    break;

                case ".p7r":

                    contentType = "application/x-pkcs7-certreqresp";

                    break;

                case ".p7s":

                    contentType = "application/x-pkcs7-signature";

                    break;

                case ".pbm":

                    contentType = "image/x-portable-bitmap";

                    break;

                case ".pdf":

                    contentType = "application/pdf";

                    break;

                case ".pfx":

                    contentType = "application/x-pkcs12";

                    break;

                case ".pgm":

                    contentType = "image/x-portable-graymap";

                    break;

                case ".pko":

                    contentType = "application/ynd.ms-pkipko";

                    break;

                case ".pma":

                    contentType = "application/x-perfmon";

                    break;

                case ".pmc":

                    contentType = "application/x-perfmon";

                    break;

                case ".pml":

                    contentType = "application/x-perfmon";

                    break;

                case ".pmr":

                    contentType = "application/x-perfmon";

                    break;

                case ".pmw":

                    contentType = "application/x-perfmon";

                    break;

                case ".pnm":

                    contentType = "image/x-portable-anymap";

                    break;

                case ".pot":

                    contentType = "application/vnd.ms-powerpoint";

                    break;

                case ".pot,":

                    contentType = "application/vnd.ms-powerpoint";

                    break;

                case ".ppm":

                    contentType = "image/x-portable-pixmap";

                    break;

                case ".pps":

                    contentType = "application/vnd.ms-powerpoint";

                    break;

                case ".ppt":

                    contentType = "application/vnd.ms-powerpoint";

                    break;

                case ".prf":

                    contentType = "application/pics-rules";

                    break;

                case ".ps":

                    contentType = "application/postscript";

                    break;

                case ".pub":

                    contentType = "application/x-mspublisher";

                    break;

                case ".qt":

                    contentType = "video/quicktime";

                    break;

                case ".ra":

                    contentType = "audio/x-pn-realaudio";

                    break;

                case ".ram":

                    contentType = "audio/x-pn-realaudio";

                    break;

                case ".ras":

                    contentType = "image/x-cmu-raster";

                    break;

                case ".rgb":

                    contentType = "image/x-rgb";

                    break;

                case ".rmi":

                    contentType = "audio/mid";

                    break;

                case ".roff":

                    contentType = "application/x-troff";

                    break;

                case ".rtf":

                    contentType = "application/rtf";

                    break;

                case ".rtx":

                    contentType = "text/richtext";

                    break;

                case ".scd":

                    contentType = "application/x-msschedule";

                    break;

                case ".sct":

                    contentType = "text/scriptlet";

                    break;

                case ".setpay":

                    contentType = "application/set-payment-initiation";

                    break;

                case ".setreg":

                    contentType = "application/set-registration-initiation";

                    break;

                case ".sh":

                    contentType = "application/x-sh";

                    break;

                case ".shar":

                    contentType = "application/x-shar";

                    break;

                case ".sit":

                    contentType = "application/x-stuffit";

                    break;

                case ".snd":

                    contentType = "audio/basic";

                    break;

                case ".spc":

                    contentType = "application/x-pkcs7-certificates";

                    break;

                case ".spl":

                    contentType = "application/futuresplash";

                    break;

                case ".src":

                    contentType = "application/x-wais-source";

                    break;

                case ".sst":

                    contentType = "application/vnd.ms-pkicertstore";

                    break;

                case ".stl":

                    contentType = "application/vnd.ms-pkistl";

                    break;

                case ".stm":

                    contentType = "text/html";

                    break;

                case ".sv4cpio":

                    contentType = "application/x-sv4cpio";

                    break;

                case ".sv4crc":

                    contentType = "application/x-sv4crc";

                    break;

                case ".svg":

                    contentType = "image/svg+xml";

                    break;

                case ".swf":

                    contentType = "application/x-shockwave-flash";

                    break;

                case ".t":

                    contentType = "application/x-troff";

                    break;

                case ".tar":

                    contentType = "application/x-tar";

                    break;

                case ".tcl":

                    contentType = "application/x-tcl";

                    break;

                case ".tex":

                    contentType = "application/x-tex";

                    break;

                case ".texi":

                    contentType = "application/x-texinfo";

                    break;

                case ".texinfo":

                    contentType = "application/x-texinfo";

                    break;

                case ".tgz":

                    contentType = "application/x-compressed";

                    break;

                case ".tif":

                    contentType = "image/tiff";

                    break;

                case ".tiff":

                    contentType = "image/tiff";

                    break;

                case ".tr":

                    contentType = "application/x-troff";

                    break;

                case ".trm":

                    contentType = "application/x-msterminal";

                    break;

                case ".tsv":

                    contentType = "text/tab-separated-values";

                    break;

                case ".txt":

                    contentType = "text/plain";

                    break;

                case ".uls":

                    contentType = "text/iuls";

                    break;

                case ".ustar":

                    contentType = "application/x-ustar";

                    break;

                case ".vcf":

                    contentType = "text/x-vcard";

                    break;

                case ".vrml":

                    contentType = "x-world/x-vrml";

                    break;

                case ".wav":

                    contentType = "audio/x-wav";

                    break;

                case ".wcm":

                    contentType = "application/vnd.ms-works";

                    break;

                case ".wdb":

                    contentType = "application/vnd.ms-works";

                    break;

                case ".wks":

                    contentType = "application/vnd.ms-works";

                    break;

                case ".wmf":

                    contentType = "application/x-msmetafile";

                    break;

                case ".wps":

                    contentType = "application/vnd.ms-works";

                    break;

                case ".wri":

                    contentType = "application/x-mswrite";

                    break;

                case ".wrl":

                    contentType = "x-world/x-vrml";

                    break;

                case ".wrz":

                    contentType = "x-world/x-vrml";

                    break;

                case ".xaf":

                    contentType = "x-world/x-vrml";

                    break;

                case ".xbm":

                    contentType = "image/x-xbitmap";

                    break;

                case ".xla":

                    contentType = "application/vnd.ms-excel";

                    break;

                case ".xlc":

                    contentType = "application/vnd.ms-excel";

                    break;

                case ".xlm":

                    contentType = "application/vnd.ms-excel";

                    break;

                case ".xls":

                    contentType = "application/vnd.ms-excel";

                    break;

                case ".xlt":

                    contentType = "application/vnd.ms-excel";

                    break;

                case ".xlw":

                    contentType = "application/vnd.ms-excel";

                    break;

                case ".xof":

                    contentType = "x-world/x-vrml";

                    break;

                case ".xpm":

                    contentType = "image/x-xpixmap";

                    break;

                case ".xwd":

                    contentType = "image/x-xwindowdump";

                    break;

                case ".z":

                    contentType = "application/x-compress";

                    break;

                case ".zip":

                    contentType = "application/zip";

                    break;



                default:

                    contentType = "";

                    break;

            }

            #endregion



            return contentType;

        }



        public static T GetValueOrDefault<T>(this IDataRecord row, string fieldName)

        {

            int ordinal = row.GetOrdinal(fieldName);

            return row.GetValueOrDefault<T>(ordinal);

        }



        public static T GetValueOrDefault<T>(this IDataRecord row, int ordinal)

        {

            return (T) (row.IsDBNull(ordinal) ? default(T) : row.GetValue(ordinal));

        }



        public static byte[] StreamToBytes(this Stream input)

        {

            int capacity = input.CanSeek ? (int) input.Length : 0;

            using (MemoryStream output = new MemoryStream(capacity))

            {

                int readLength;

                byte[] buffer = new byte[4096];



                do

                {

                    readLength = input.Read(buffer, 0, buffer.Length);

                    output.Write(buffer, 0, readLength);

                } while (readLength != 0);



                return output.ToArray();

            }

        }



        private static IList<string> SplitIntoChunks(this string text, int chunkSize)

        {

            List<string> chunks = new List<string>();

            int offset = 0;

            while (offset < text.Length)

            {

                int size = Math.Min(chunkSize, text.Length - offset);

                chunks.Add(text.Substring(offset, size));

                offset += size;

            }

            return chunks;

        }

    }



    /// <summary>

    /// 

    /// </summary>

    public enum RunState

    {

        /// <summary>

        /// 

        /// </summary>

        Idle = 0,

        /// <summary>

        /// 

        /// </summary>

        Running

    }



    /// <summary>

    /// 

    /// </summary>

    public enum PortMode

    {

        /// <summary>

        /// 

        /// </summary>

        FirstAvailable = 0,

        /// <summary>

        /// 

        /// </summary>

        Specific

    }



    /// <summary>

    /// 

    /// </summary>

    public enum ErrorField

    {

        /// <summary>

        /// 

        /// </summary>

        None,

        /// <summary>

        /// 

        /// </summary>

        ApplicationPath,

        /// <summary>

        /// 

        /// </summary>

        VirtualPath,

        /// <summary>

        /// 

        /// </summary>

        HostName,

        /// <summary>

        /// 

        /// </summary>

        IsAddHost,

        /// <summary>

        /// 

        /// </summary>

// ReSharper disable InconsistentNaming

        IPAddress,

// ReSharper restore InconsistentNaming

        /// <summary>

        /// 

        /// </summary>

// ReSharper disable InconsistentNaming

        IPAddressAny,

// ReSharper restore InconsistentNaming

        /// <summary>

        /// 

        /// </summary>

// ReSharper disable InconsistentNaming

        IPAddressLoopBack,

// ReSharper restore InconsistentNaming

        /// <summary>

        /// 

        /// </summary>

        Port,

        /// <summary>

        /// 

        /// </summary>

        PortRangeStart,

        /// <summary>

        /// 

        /// </summary>

        PortRangeEnd,

        /// <summary>

        /// 

        /// </summary>

        PortRange

    }



    /// <summary>

    /// 

    /// </summary>

// ReSharper disable InconsistentNaming

    public enum IPMode

// ReSharper restore InconsistentNaming

    {

        /// <summary>

        /// 

        /// </summary>

        Loopback = 0,

        /// <summary>

        /// 

        /// </summary>

        Any,

        /// <summary>

        /// 

        /// </summary>

        Specific

    }



    /// <summary>

    /// 

    /// </summary>

    public enum RunMode

    {

        /// <summary>

        /// 

        /// </summary>

        Server,

        /// <summary>

        /// 

        /// </summary>

        Hostsfile

    }



    /// <summary>

    /// 

    /// </summary>

    internal class CassiniException : Exception

    {

        public CassiniException(string message, ErrorField field, Exception innerException)

            : base(message, innerException)

        {

            Field = field;

        }



        public CassiniException(string message, ErrorField field)

            : this(message, field, null)

        {

        }



        public ErrorField Field { get; set; }

    }

}
Common类
//  **********************************************************************************

//  CassiniDev - http://cassinidev.codeplex.com

// 

//  Copyright (c) 2010 Sky Sanders. All rights reserved.

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

//  

//  This source code is subject to terms and conditions of the Microsoft Public

//  License (Ms-PL). A copy of the license can be found in the license.txt file

//  included in this distribution.

//  

//  You must not remove this notice, or any other, from this software.

//  

//  **********************************************************************************



#region



using System;

using System.Collections.Generic;

using System.Globalization;

using System.IO;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Web;



#endregion



namespace SimpleWebServer

{

    /// <summary>

    /// 

    /// </summary>

    public class Connection : MarshalByRefObject

    {

        private const int HttpForbidden = 403;



// ReSharper disable InconsistentNaming

        private const int HttpOK = 200;

// ReSharper restore InconsistentNaming



        private readonly MemoryStream _responseContent;

        /// <summary>

        /// 

        /// </summary>

        public List<string> Plugins = new List<string>();

        private readonly Server _server;



        private Socket _socket;



        internal Connection(Server server, Socket socket)

        {

            Plugins = server.Plugins;

            Id = Guid.NewGuid();

            _responseContent = new MemoryStream();

            _server = server;

            _socket = socket;

        }



        /// <summary>

        /// 

        /// </summary>

        public bool Connected

        {

            get { return _socket.Connected; }

        }



        /// <summary>

        /// 

        /// </summary>

        public Guid Id { get; private set; }



        /// <summary>

        /// 

        /// </summary>

// ReSharper disable InconsistentNaming

        public string LocalIP

// ReSharper restore InconsistentNaming

        {

            get

            {

                IPEndPoint ep = (IPEndPoint) _socket.LocalEndPoint;

                return (ep != null && ep.Address != null) ? ep.Address.ToString() : "127.0.0.1";

            }

        }



        

// ReSharper disable InconsistentNaming

        /// <summary>

        /// 

        /// </summary>

        public string RemoteIP

// ReSharper restore InconsistentNaming

        {

            get

            {

                IPEndPoint ep = (IPEndPoint) _socket.RemoteEndPoint;

                return (ep != null && ep.Address != null) ? ep.Address.ToString() : "127.0.0.1";

            }

        }



        /// <summary>

        /// 

        /// </summary>

        public void Close()

        {

            



            try

            {

                _socket.Shutdown(SocketShutdown.Both);

                _socket.Close();

            }

                // ReSharper disable EmptyGeneralCatchClause

            catch

                // ReSharper restore EmptyGeneralCatchClause

            {

            }

            finally

            {

                _socket = null;

            }

        }



        /// <summary>

        /// </summary>

        public override object InitializeLifetimeService()

        {

            return null;

        }



        /// <summary>

        /// 

        /// </summary>

        /// <param name="maxBytes"></param>

        /// <returns></returns>

        public byte[] ReadRequestBytes(int maxBytes)

        {

            try

            {

                if (WaitForRequestBytes() == 0)

                {

                    return null;

                }



                int numBytes = _socket.Available;



                if (numBytes > maxBytes)

                {

                    numBytes = maxBytes;

                }



                int numReceived = 0;



                byte[] buffer = new byte[numBytes];



                if (numBytes > 0)

                {

                    numReceived = _socket.Receive(buffer, 0, numBytes, SocketFlags.None);

                }



                if (numReceived < numBytes)

                {

                    byte[] tempBuffer = new byte[numReceived];



                    if (numReceived > 0)

                    {

                        Buffer.BlockCopy(buffer, 0, tempBuffer, 0, numReceived);

                    }



                    buffer = tempBuffer;

                }



                return buffer;

            }

            catch

            {

                return null;

            }

        }



        /// <summary>

        /// 

        /// </summary>

        /// <returns></returns>

        public int WaitForRequestBytes()

        {

            int availBytes = 0;



            try

            {

                if (_socket.Available == 0)

                {

                    _socket.Poll(100000, SelectMode.SelectRead);



                    if (_socket.Available == 0 && _socket.Connected)

                    {

                        _socket.Poll(30000000, SelectMode.SelectRead);

                    }

                }



                availBytes = _socket.Available;

            }

                // ReSharper disable EmptyGeneralCatchClause

            catch

                // ReSharper restore EmptyGeneralCatchClause

            {

            }



            return availBytes;

        }



        /// <summary>

        /// 

        /// </summary>

        public void Write100Continue()

        {

            WriteEntireResponseFromString(100, null, null, true);

        }



        internal void Write200Continue()

        {

            WriteEntireResponseFromString(200, null, string.Empty, true);

        }



        /// <summary>

        /// 

        /// </summary>

        /// <param name="data"></param>

        /// <param name="offset"></param>

        /// <param name="length"></param>

        public void WriteBody(byte[] data, int offset, int length)

        {

            try

            {

                _responseContent.Write(data, 0, data.Length);

                _socket.Send(data, offset, length, SocketFlags.None);

            }

            catch (SocketException)

            {

            }

        }



        /// <summary>

        /// 

        /// </summary>

        /// <param name="fileName"></param>

        /// <param name="keepAlive"></param>

        public void WriteEntireResponseFromFile(String fileName, bool keepAlive)

        {

            if (!File.Exists(fileName))

            {

                WriteErrorAndClose(404);

                return;

            }



            // Deny the request if the contentType cannot be recognized.



            string contentType = CommonExtensions.GetContentType(fileName);



            //TODO: i am pretty sure this is unnecessary

            if (contentType == null)

            {

                WriteErrorAndClose(HttpForbidden);

                return;

            }



            string contentTypeHeader = "Content-Type: " + contentType + "\r\n";



            bool completed = false;

            FileStream fs = null;



            try

            {

                fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);

                int len = (int) fs.Length;

                byte[] fileBytes = new byte[len];

                int bytesRead = fs.Read(fileBytes, 0, len);



                String headers = MakeResponseHeaders(HttpOK, contentTypeHeader, bytesRead, keepAlive);

                _socket.Send(Encoding.UTF8.GetBytes(headers));



                _socket.Send(fileBytes, 0, bytesRead, SocketFlags.None);



                completed = true;

            }

            catch (SocketException)

            {

            }

            finally

            {

                if (!keepAlive || !completed)

                {

                    Close();

                }



                if (fs != null)

                {

                    fs.Close();

                }

            }

        }



        /// <summary>

        /// 

        /// </summary>

        /// <param name="statusCode"></param>

        /// <param name="extraHeaders"></param>

        /// <param name="body"></param>

        /// <param name="keepAlive"></param>

        public void WriteEntireResponseFromString(int statusCode, String extraHeaders, String body, bool keepAlive)

        {

            try

            {

                int bodyLength = (body != null) ? Encoding.UTF8.GetByteCount(body) : 0;

                string headers = MakeResponseHeaders(statusCode, extraHeaders, bodyLength, keepAlive);



                _socket.Send(Encoding.UTF8.GetBytes(headers + body));

            }

            catch (SocketException)

            {

            }

            finally

            {

                if (!keepAlive)

                {

                    Close();

                }

            }

        }



        /// <summary>

        /// 

        /// </summary>

        /// <param name="statusCode"></param>

        /// <param name="message"></param>

        public void WriteErrorAndClose(int statusCode, string message)

        {

            WriteEntireResponseFromString(statusCode, null, GetErrorResponseBody(statusCode, message), false);

        }



        /// <summary>

        /// 

        /// </summary>

        /// <param name="statusCode"></param>

        public void WriteErrorAndClose(int statusCode)

        {

            WriteErrorAndClose(statusCode, null);

        }



        /// <summary>

        /// 

        /// </summary>

        /// <param name="statusCode"></param>

        /// <param name="extraHeaders"></param>

        public void WriteErrorWithExtraHeadersAndKeepAlive(int statusCode, string extraHeaders)

        {

            WriteEntireResponseFromString(statusCode, extraHeaders, GetErrorResponseBody(statusCode, null), true);

        }



        /// <summary>

        /// 

        /// </summary>

        /// <param name="statusCode"></param>

        /// <param name="extraHeaders"></param>

        public void WriteHeaders(int statusCode, String extraHeaders)

        {

            string headers = MakeResponseHeaders(statusCode, extraHeaders, -1, false);



            try

            {

                _socket.Send(Encoding.UTF8.GetBytes(headers));

            }

            catch (SocketException)

            {

            }

        }



        private string GetErrorResponseBody(int statusCode, string message)

        {

            string body = Messages.FormatErrorMessageBody(statusCode, _server.VirtualPath);



            if (!string.IsNullOrEmpty(message))

            {

                body += "\r\n<!--\r\n" + message + "\r\n-->";

            }



            return body;

        }



        //private void InitializeLogInfo()

        //{

        //    _requestLog = new LogInfo

        //        {

        //            Created = DateTime.Now,

        //            ConversationId = Id,

        //            RowType = 1,

        //            Identity = _server.GetProcessUser(),

        //            PhysicalPath = _server.PhysicalPath

        //        };



        //    _responseLog = new LogInfo

        //        {

        //            ConversationId = Id,

        //            RowType = 2

        //        };

        //}



        private static string MakeResponseHeaders(int statusCode, string moreHeaders, int contentLength, bool keepAlive)

        {

            StringBuilder sb = new StringBuilder();



            sb.Append("HTTP/1.1 " + statusCode + " " + HttpWorkerRequest.GetStatusDescription(statusCode) + "\r\n");

            sb.Append("Server: Cassini/" + Messages.VersionString + "\r\n");

            sb.Append("Date: " + DateTime.Now.ToUniversalTime().ToString("R", DateTimeFormatInfo.InvariantInfo) + "\r\n");



            if (contentLength >= 0)

            {

                sb.Append("Content-Length: " + contentLength + "\r\n");

            }



            if (moreHeaders != null)

            {

                sb.Append(moreHeaders);

            }



            if (!keepAlive)

            {

                sb.Append("Connection: Close\r\n");

            }



            sb.Append("\r\n");



            return sb.ToString();

        }

    }

}
Connection类
#region



using System;

using System.Globalization;

using System.Security.Permissions;

using System.Security.Principal;

using System.Threading;

using System.Web;

using System.Web.Hosting;



#endregion



namespace SimpleWebServer

{

    public class Host : MarshalByRefObject, IRegisteredObject

    {

        private bool _disableDirectoryListing;



        private string _installPath;



        private string _lowerCasedClientScriptPathWithTrailingSlash;



        private string _lowerCasedVirtualPath;



        private string _lowerCasedVirtualPathWithTrailingSlash;



        private volatile int _pendingCallsCount;



        private string _physicalClientScriptPath;



        private string _physicalPath;



        private int _port;



        private bool _requireAuthentication;



        private Server _server;



        private string _virtualPath;



        public AppDomain AppDomain

        {

            get { return AppDomain.CurrentDomain; }

        }



        public Host()

        {

            HostingEnvironment.RegisterObject(this);

        }



        public bool DisableDirectoryListing

        {

            get { return _disableDirectoryListing; }

        }



        public string InstallPath

        {

            get { return _installPath; }

        }



        public string NormalizedClientScriptPath

        {

            get { return _lowerCasedClientScriptPathWithTrailingSlash; }

        }



        public string NormalizedVirtualPath

        {

            get { return _lowerCasedVirtualPathWithTrailingSlash; }

        }



        public string PhysicalClientScriptPath

        {

            get { return _physicalClientScriptPath; }

        }



        public string PhysicalPath

        {

            get { return _physicalPath; }

        }



        public int Port

        {

            get { return _port; }

        }



        public bool RequireAuthentication

        {

            get { return _requireAuthentication; }

        }



        public string VirtualPath

        {

            get { return _virtualPath; }

        }



        #region IRegisteredObject Members



        void IRegisteredObject.Stop(bool immediate)

        {

            // Unhook the Host so Server will process the requests in the new appdomain.



            if (_server != null)

            {

                _server.HostStopped();

            }



            // Make sure all the pending calls complete before this Object is unregistered.

            WaitForPendingCallsToFinish();



            HostingEnvironment.UnregisterObject(this);



            Thread.Sleep(100);

            HttpRuntime.Close();

            Thread.Sleep(100);

        }



        #endregion



        public void Configure(Server server, int port, string virtualPath, string physicalPath,

                              bool requireAuthentication)

        {

            Configure(server, port, virtualPath, physicalPath, requireAuthentication, false);

        }



        public void Configure(Server server, int port, string virtualPath, string physicalPath)

        {

            Configure(server, port, virtualPath, physicalPath, false, false);

        }



        public void Configure(Server server, int port, string virtualPath, string physicalPath,

                              bool requireAuthentication, bool disableDirectoryListing)

        {

            _server = server;



            _port = port;

            _installPath = null;

            _virtualPath = virtualPath;

            _requireAuthentication = requireAuthentication;

            _disableDirectoryListing = disableDirectoryListing;

            _lowerCasedVirtualPath = CultureInfo.InvariantCulture.TextInfo.ToLower(_virtualPath);

            _lowerCasedVirtualPathWithTrailingSlash = virtualPath.EndsWith("/", StringComparison.Ordinal)

                                                          ? virtualPath

                                                          : virtualPath + "/";

            _lowerCasedVirtualPathWithTrailingSlash =

                CultureInfo.InvariantCulture.TextInfo.ToLower(_lowerCasedVirtualPathWithTrailingSlash);

            _physicalPath = physicalPath;

            _physicalClientScriptPath = HttpRuntime.AspClientScriptPhysicalPath + "\\";

            _lowerCasedClientScriptPathWithTrailingSlash =

                CultureInfo.InvariantCulture.TextInfo.ToLower(HttpRuntime.AspClientScriptVirtualPath + "/");

        }



        public SecurityIdentifier GetProcessSid()

        {

            using (WindowsIdentity identity = new WindowsIdentity(_server.GetProcessToken()))

            {

                return identity.User;

            }

        }



        public IntPtr GetProcessToken()

        {

            new SecurityPermission(PermissionState.Unrestricted).Assert();

            return _server.GetProcessToken();

        }



        public string GetProcessUser()

        {

            return _server.GetProcessUser();

        }



        public override object InitializeLifetimeService()

        {

            // never expire the license

            return null;

        }



        public bool IsVirtualPathAppPath(string path)

        {

            if (path == null)

            {

                return false;

            }

            path = CultureInfo.InvariantCulture.TextInfo.ToLower(path);

            return (path == _lowerCasedVirtualPath || path == _lowerCasedVirtualPathWithTrailingSlash);

        }



        public bool IsVirtualPathInApp(string path, out bool isClientScriptPath)

        {

            isClientScriptPath = false;



            if (path == null)

            {

                return false;

            }



            if (_virtualPath == "/" && path.StartsWith("/", StringComparison.Ordinal))

            {

                if (path.StartsWith(_lowerCasedClientScriptPathWithTrailingSlash, StringComparison.Ordinal))

                {

                    isClientScriptPath = true;

                }

                return true;

            }



            path = CultureInfo.InvariantCulture.TextInfo.ToLower(path);



            if (path.StartsWith(_lowerCasedVirtualPathWithTrailingSlash, StringComparison.Ordinal))

            {

                return true;

            }



            if (path == _lowerCasedVirtualPath)

            {

                return true;

            }



            if (path.StartsWith(_lowerCasedClientScriptPathWithTrailingSlash, StringComparison.Ordinal))

            {

                isClientScriptPath = true;

                return true;

            }



            return false;

        }



        public bool IsVirtualPathInApp(String path)

        {

            bool isClientScriptPath;

            return IsVirtualPathInApp(path, out isClientScriptPath);

        }



        public void ProcessRequest(Connection conn,string dfPage)

        {

            // Add a pending call to make sure our thread doesn't get killed

            AddPendingCall();



            try

            {

                new Request(_server, this, conn, dfPage).Process();

            }

            finally

            {

                RemovePendingCall();

            }

        }



        [SecurityPermission(SecurityAction.Assert, Unrestricted = true)]

        public void Shutdown()

        {

            HostingEnvironment.InitiateShutdown();

        }



        private void AddPendingCall()

        {

            //TODO: investigate this issue - ref var not volitile

#pragma warning disable 0420

            Interlocked.Increment(ref _pendingCallsCount);

#pragma warning restore 0420

        }



        private void RemovePendingCall()

        {

            //TODO: investigate this issue - ref var not volitile

#pragma warning disable 0420

            Interlocked.Decrement(ref _pendingCallsCount);

#pragma warning restore 0420

        }



        private void WaitForPendingCallsToFinish()

        {

            for (; ; )

            {

                if (_pendingCallsCount <= 0)

                {

                    break;

                }



                Thread.Sleep(250);

            }

        }

    }

}
Host类
//  **********************************************************************************

//  CassiniDev - http://cassinidev.codeplex.com

// 

//  Copyright (c) 2010 Sky Sanders. All rights reserved.

//  

//  This source code is subject to terms and conditions of the Microsoft Public

//  License (Ms-PL). A copy of the license can be found in the license.txt file

//  included in this distribution.

//  

//  You must not remove this notice, or any other, from this software.

//  

//  **********************************************************************************



#region



using System;

using System.Runtime.InteropServices;



#endregion



namespace SimpleWebServer

{

    internal static class Interop

    {

        #region Structs



        [DllImport("SECUR32.DLL", CharSet = CharSet.Unicode)]

        public static extern int AcceptSecurityContext(ref SecHandle phCredential, IntPtr phContext,

                                                       ref SecBufferDesc pInput, uint fContextReq, uint TargetDataRep,

                                                       ref SecHandle phNewContext, ref SecBufferDesc pOutput,

                                                       ref uint pfContextAttr, ref long ptsTimeStamp);



        [DllImport("SECUR32.DLL", CharSet = CharSet.Unicode)]

        public static extern int AcquireCredentialsHandle(string pszPrincipal, string pszPackage, uint fCredentialUse,

                                                          IntPtr pvLogonID, IntPtr pAuthData, IntPtr pGetKeyFn,

                                                          IntPtr pvGetKeyArgument, ref SecHandle phCredential,

                                                          ref long ptsExpiry);



        [DllImport("KERNEL32.DLL", CharSet = CharSet.Unicode)]

        public static extern int CloseHandle(IntPtr phToken);



        [DllImport("SECUR32.DLL", CharSet = CharSet.Unicode)]

        public static extern int DeleteSecurityContext(ref SecHandle phContext);



        /// <summary>

        /// FIX: #12506

        /// </summary>

        [DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]

        public static extern int FindMimeFromData(IntPtr pBC, [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,

                                                  [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1,

                                                      SizeParamIndex = 3)] byte[] pBuffer, int cbSize,

                                                  [MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed,

                                                  int dwMimeFlags, out IntPtr ppwzMimeOut, int dwReserved);



        [DllImport("SECUR32.DLL", CharSet = CharSet.Unicode)]

        public static extern int FreeCredentialsHandle(ref SecHandle phCredential);



        [DllImport("kernel32.dll", EntryPoint = "GetConsoleScreenBufferInfo", SetLastError = true,

            CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

        public static extern int GetConsoleScreenBufferInfo(int hConsoleOutput,

                                                            ref CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);



        [DllImport("KERNEL32.DLL", SetLastError = true)]

        public static extern IntPtr GetCurrentThread();



        [DllImport("kernel32.dll", EntryPoint = "GetStdHandle", SetLastError = true, CharSet = CharSet.Auto,

            CallingConvention = CallingConvention.StdCall)]

        public static extern int GetStdHandle(int nStdHandle);



        [DllImport("ADVAPI32.DLL", SetLastError = true)]

        public static extern bool ImpersonateSelf(int level);



        [DllImport("ADVAPI32.DLL", SetLastError = true)]

        public static extern int OpenThreadToken(IntPtr thread, int access, bool openAsSelf, ref IntPtr hToken);



        [DllImport("SECUR32.DLL", CharSet = CharSet.Unicode)]

        public static extern int QuerySecurityContextToken(ref SecHandle phContext, ref IntPtr phToken);



        [DllImport("ADVAPI32.DLL", SetLastError = true)]

        public static extern int RevertToSelf();



        #region Nested type: CONSOLE_SCREEN_BUFFER_INFO



        public struct CONSOLE_SCREEN_BUFFER_INFO

        {

            internal COORD dwCursorPosition;

            internal COORD dwMaximumWindowSize;

            internal COORD dwSize;

            internal SMALL_RECT srWindow;

            internal Int16 wAttributes;

        }



        #endregion



        #region Nested type: COORD



        public struct COORD

        {

            internal Int16 x;

            internal Int16 y;

        }



        #endregion



        #region Nested type: SecBuffer



        [StructLayout(LayoutKind.Sequential)]

        public struct SecBuffer

        {

            // ReSharper disable InconsistentNaming

            public uint cbBuffer;

            public uint BufferType;

            public IntPtr pvBuffer;

            // ReSharper restore InconsistentNaming

        }



        #endregion



        #region Nested type: SecBufferDesc



        [StructLayout(LayoutKind.Sequential)]

        public struct SecBufferDesc

        {

            // ReSharper disable InconsistentNaming

            public uint ulVersion;

            public uint cBuffers;

            public IntPtr pBuffers;

            // ReSharper restore InconsistentNaming

        }



        #endregion



        #region Nested type: SecHandle



        [StructLayout(LayoutKind.Sequential)]

        public struct SecHandle

        {

            // ReSharper disable InconsistentNaming

            public IntPtr dwLower;

            public IntPtr dwUpper;

            // ReSharper restore InconsistentNaming

        }



        #endregion



        #region Nested type: SMALL_RECT



        public struct SMALL_RECT

        {

            internal Int16 Bottom;

            internal Int16 Left;

            internal Int16 Right;

            internal Int16 Top;

        }



        #endregion



        #endregion

    }

}
Interop
//  **********************************************************************************

//  CassiniDev - http://cassinidev.codeplex.com

// 

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

//  

//  This source code is subject to terms and conditions of the Microsoft Public

//  License (Ms-PL). A copy of the license can be found in the license.txt file

//  included in this distribution.

//  

//  You must not remove this notice, or any other, from this software.

//  

//  **********************************************************************************



#region



using System.IO;

using System.Text;

using System.Web;



#endregion



namespace SimpleWebServer

{

    /// <summary>

    /// TODO: get this into resources

    /// </summary>

    internal static class Messages

    {

        private const string _dirListingDirFormat =

            @"{0,38:dddd, MMMM dd, yyyy hh:mm tt}        &lt;dir&gt; <A href=""{1}/"">{2}</A>

";



        private const string _dirListingFileFormat =

            @"{0,38:dddd, MMMM dd, yyyy hh:mm tt} {1,12:n0} <A href=""{2}"">{3}</A>

";



        private const string _dirListingFormat1 =

            @"<html>

    <head>

    <title>Directory Listing -- {0}</title>

";



        private const string _dirListingFormat2 =

            @"    </head>

    <body bgcolor=""white"">



    <h2> <i>Directory Listing -- {0}</i> </h2></span>



            <hr width=100% size=1 color=silver>



<PRE>

";



        private const string _dirListingParentFormat =

            @"<A href=""{0}"">[To Parent Directory]</A>



";



        private const string _httpErrorFormat1 =

            @"<html>

    <head>

        <title>{0}</title>

";



        private const string _httpStyle =

            @"        <style>

            body {font-family:""Verdana"";font-weight:normal;font-size: 8pt;color:black;} 

            p {font-family:""Verdana"";font-weight:normal;color:black;margin-top: -5px}

            b {font-family:""Verdana"";font-weight:bold;color:black;margin-top: -5px}

            h1 { font-family:""Verdana"";font-weight:normal;font-size:18pt;color:red }

            h2 { font-family:""Verdana"";font-weight:normal;font-size:14pt;color:maroon }

            pre {font-family:""Lucida Console"";font-size: 8pt}

            .marker {font-weight: bold; color: black;text-decoration: none;}

            .version {color: gray;}

            .error {margin-bottom: 10px;}

            .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }

        </style>

";



        private static readonly string _dirListingTail =

            @"</PRE>

            <hr width=100% size=1 color=silver>



            <b>Version Information:</b>&nbsp;CassiniDev Web Server " +

            VersionString + @"



            </font>



    </body>

</html>

";



        private static readonly string _httpErrorFormat2 =

            @"    </head>

    <body bgcolor=""white"">



            <span><h1>Server Error in '{0}' Application.<hr width=100% size=1 color=silver></h1>



            <h2> <i>HTTP Error {1} - {2}.</i> </h2></span>



            <hr width=100% size=1 color=silver>



            <b>Version Information:</b>&nbsp;CassiniDev Web Server " +

            VersionString + @"



            </font>



    </body>

</html>

";



        public static string VersionString = typeof (Server).Assembly.GetName().Version.ToString();



        public static string FormatDirectoryListing(string dirPath, string parentPath, FileSystemInfo[] elements)

        {

            StringBuilder sb = new StringBuilder();



            sb.Append(string.Format(_dirListingFormat1, dirPath));

            sb.Append(_httpStyle);

            sb.Append(string.Format(_dirListingFormat2, dirPath));



            if (parentPath != null)

            {

                if (!parentPath.EndsWith("/"))

                {

                    parentPath += "/";

                }



                sb.Append(string.Format(_dirListingParentFormat, parentPath));

            }



            if (elements != null)

            {

                for (int i = 0; i < elements.Length; i++)

                {

                    if (elements[i] is FileInfo)

                    {

                        FileInfo fi = (FileInfo) elements[i];

                        sb.Append(string.Format(_dirListingFileFormat,

                                                fi.LastWriteTime, fi.Length, fi.Name, fi.Name));

                    }

                    else if (elements[i] is DirectoryInfo)

                    {

                        DirectoryInfo di = (DirectoryInfo) elements[i];

                        sb.Append(string.Format(_dirListingDirFormat,

                                                di.LastWriteTime, di.Name, di.Name));

                    }

                }

            }



            sb.Append(_dirListingTail);

            return sb.ToString();

        }



        public static string FormatErrorMessageBody(int statusCode, string appName)

        {

            string desc = HttpWorkerRequest.GetStatusDescription(statusCode);



            return string.Format(_httpErrorFormat1, desc)

                   + _httpStyle

                   + string.Format(_httpErrorFormat2, appName, statusCode, desc);

        }

    }

}
Messages
//  **********************************************************************************

//  CassiniDev - http://cassinidev.codeplex.com

// 

//  Copyright (c) 2010 Sky Sanders. All rights reserved.

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

//  

//  This source code is subject to terms and conditions of the Microsoft Public

//  License (Ms-PL). A copy of the license can be found in the license.txt file

//  included in this distribution.

//  

//  You must not remove this notice, or any other, from this software.

//  

//  **********************************************************************************



#region



using System;

using System.Collections.Generic;

using System.Collections.Specialized;

using System.Globalization;

using System.IO;

using System.Linq;

using System.Reflection;

using System.Security;

using System.Security.Permissions;

using System.Text;

using System.Web;

using System.Web.Hosting;

using Microsoft.Win32.SafeHandles;

using System.Security.Principal;



#endregion



namespace SimpleWebServer

{

    public class Request : SimpleWorkerRequest

    {

        private const int MaxChunkLength = 64 * 1024;



        private const int MaxHeaderBytes = 32 * 1024;



        private static readonly char[] BadPathChars = new[] { '%', '>', '<', ':', '\\' };



        private static readonly string[] DefaultFileNames = new[] { "default.aspx", "default.htm", "default.html" };



        private static readonly char[] IntToHex = new[]

            {

                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'

            };



        private static readonly string[] RestrictedDirs = new[]

            {

                "/bin",

                "/app_browsers",

                "/app_code",

                "/app_data",

                "/app_localresources",

                "/app_globalresources",

                "/app_webreferences"

            };



        private readonly IStackWalk _connectionPermission = new PermissionSet(PermissionState.Unrestricted);

        private readonly Host _host;

        private readonly Server _server;



        private string _allRawHeaders;



        private byte[] _body;



        private int _bodyLength;



        private Connection _connection;



        private int _contentLength;



        // security permission to Assert remoting calls to _connection

        private int _endHeadersOffset;



        private string _filePath;



        private byte[] _headerBytes;



        private List<ByteString> _headerByteStrings;



        private bool _headersSent;



        // parsed request data



        private bool _isClientScriptPath;



        private string[] _knownRequestHeaders;



        private string _path;



        private string _pathInfo;



        private string _pathTranslated;



        private string _protocol;



        private string _queryString;

        private byte[] _queryStringBytes;



        private List<byte[]> _responseBodyBytes;



        private StringBuilder _responseHeadersBuilder;



        private int _responseStatus;



        private bool _specialCaseStaticFileHeaders;



        private int _startHeadersOffset;



        private string[][] _unknownRequestHeaders;



        private string _url;



        private string _verb;



        private string _dfPage;





        public Request(Server server, Host host, Connection connection,string dfPage)

            : base(String.Empty, String.Empty, null)

        {

            _connectionPermission = new PermissionSet(PermissionState.Unrestricted);

            _server = server;

            _host = host;

            _connection = connection;

            _dfPage = dfPage;

        }



        public override void CloseConnection()

        {

            _connectionPermission.Assert();

            _connection.Close();

        }



        public override void EndOfRequest()

        {

            Connection conn = _connection;

            if (conn != null)

            {

                _connection = null;

                _server.OnRequestEnd(conn);

            }



        }



        public override void FlushResponse(bool finalFlush)

        {

            if (_responseStatus == 404 && !_headersSent && finalFlush && _verb == "GET")

            {

                

                // attempt directory listing

                if (ProcessDirectoryListingRequest())

                {

                    return;

                }

            }



            _connectionPermission.Assert();



            if (!_headersSent)

            {

                _connection.WriteHeaders(_responseStatus, _responseHeadersBuilder.ToString());



                _headersSent = true;

            }

            foreach (byte[] bytes in _responseBodyBytes)

            {

                _connection.WriteBody(bytes, 0, bytes.Length);

            }



            _responseBodyBytes = new List<byte[]>();



            if (finalFlush)

            {

                _connection.Close();

            }

        }



        public override string GetAppPath()

        {

            return _host.VirtualPath;

        }



        public override string GetAppPathTranslated()

        {

            return _host.PhysicalPath;

        }



        public override string GetFilePath()

        {

            return _filePath;

        }



        public override string GetFilePathTranslated()

        {

            return _pathTranslated;

        }



        public override string GetHttpVerbName()

        {

            return _verb;

        }



        public override string GetHttpVersion()

        {

            return _protocol;

        }



        public override string GetKnownRequestHeader(int index)

        {

            return _knownRequestHeaders[index];

        }



        public override string GetLocalAddress()

        {

            _connectionPermission.Assert();

            return _connection.LocalIP;

        }



        public override int GetLocalPort()

        {

            return _host.Port;

        }



        public override string GetPathInfo()

        {

            return _pathInfo;

        }



        public override byte[] GetPreloadedEntityBody()

        {

            return _body;

        }



        public override string GetQueryString()

        {

            return _queryString;

        }



        public override byte[] GetQueryStringRawBytes()

        {

            return _queryStringBytes;

        }



        public override string GetRawUrl()

        {

            return _url;

        }



        public override string GetRemoteAddress()

        {

            _connectionPermission.Assert();

            return _connection.RemoteIP;

        }



        public override int GetRemotePort()

        {

            return 0;

        }



        public override string GetServerName()

        {

            string localAddress = GetLocalAddress();

            if (localAddress.Equals("127.0.0.1"))

            {

                return "localhost";

            }

            return localAddress;

        }



        public override string GetServerVariable(string name)

        {

            string processUser = string.Empty;

            string str2 = name;

            if (str2 == null)

            {

                return processUser;

            }

            if (str2 != "ALL_RAW")

            {

                if (str2 != "SERVER_PROTOCOL")

                {

                    if (str2 == "LOGON_USER")

                    {

                        if (GetUserToken() != IntPtr.Zero)

                        {

                            processUser = _host.GetProcessUser();

                        }

                        return processUser;

                    }

                    if ((str2 == "AUTH_TYPE") && (GetUserToken() != IntPtr.Zero))

                    {

                        processUser = "NTLM";

                    }

                    return processUser;

                }

            }

            else

            {

                return _allRawHeaders;

            }

            return _protocol;

        }



        public override string GetUnknownRequestHeader(string name)

        {

            int n = _unknownRequestHeaders.Length;



            for (int i = 0; i < n; i++)

            {

                if (string.Compare(name, _unknownRequestHeaders[i][0], StringComparison.OrdinalIgnoreCase) == 0)

                {

                    return _unknownRequestHeaders[i][1];

                }

            }



            return null;

        }



        public override string[][] GetUnknownRequestHeaders()

        {

            return _unknownRequestHeaders;

        }



        ///////////////////////////////////////////////////////////////////////////////////////////////

        // Implementation of HttpWorkerRequest



        public override string GetUriPath()

        {

            return _path;

        }



        public Connection GetConnection()

        {

            return _connection;

        }





        public override bool HeadersSent()

        {

            return _headersSent;

        }



        public override bool IsClientConnected()

        {

            _connectionPermission.Assert();

            return _connection.Connected;

        }



        public override bool IsEntireEntityBodyIsPreloaded()

        {

            return (_contentLength == _bodyLength);

        }



        public override string MapPath(string path)

        {

            string mappedPath;

            bool isClientScriptPath;



            if (string.IsNullOrEmpty(path) || path.Equals("/"))

            {

                // asking for the site root

                mappedPath = _host.VirtualPath == "/" ? _host.PhysicalPath : Environment.SystemDirectory;

            }

            else if (_host.IsVirtualPathAppPath(path))

            {

                // application path

                mappedPath = _host.PhysicalPath;

            }

            else if (_host.IsVirtualPathInApp(path, out isClientScriptPath))

            {

                if (isClientScriptPath)

                {

                    mappedPath = _host.PhysicalClientScriptPath +

                                 path.Substring(_host.NormalizedClientScriptPath.Length);

                }

                else

                {

                    // inside app but not the app path itself

                    mappedPath = _host.PhysicalPath + path.Substring(_host.NormalizedVirtualPath.Length);

                }

            }

            else

            {

                // outside of app -- make relative to app path

                if (path.StartsWith("/", StringComparison.Ordinal))

                {

                    mappedPath = _host.PhysicalPath + path.Substring(1);

                }

                else

                {

                    mappedPath = _host.PhysicalPath + path;

                }

            }



            mappedPath = mappedPath.Replace('/', '\\');



            if (mappedPath.EndsWith("\\", StringComparison.Ordinal) &&

                !mappedPath.EndsWith(":\\", StringComparison.Ordinal))

            {

                mappedPath = mappedPath.Substring(0, mappedPath.Length - 1);

            }



            return mappedPath;

        }



        [AspNetHostingPermission(SecurityAction.Assert, Level = AspNetHostingPermissionLevel.Medium)]

        public void Process()

        {

            // read the request

            if (!TryParseRequest())

            {

                return;

            }



            // 100 response to POST

            if (_verb == "POST" && _contentLength > 0 && _bodyLength < _contentLength)

            {

                _connection.Write100Continue();

            }

            if (!_host.RequireAuthentication)

            {

                // special case for client script

                if (_isClientScriptPath)

                {

                    _connection.WriteEntireResponseFromFile(

                        _host.PhysicalClientScriptPath + _path.Substring(_host.NormalizedClientScriptPath.Length), false);

                    return;

                }



                // deny access to code, bin, etc.

                if (IsRequestForRestrictedDirectory())

                {

                    _connection.WriteErrorAndClose(403);

                    return;

                }



                // special case for a request to a directory (ensure / at the end and process default documents)

                if (ProcessDirectoryRequest())

                {

                    return;

                }







                PrepareResponse();



                // Hand the processing over to HttpRuntime

                HttpRuntime.ProcessRequest(this);

            }

        }



        public override int ReadEntityBody(byte[] buffer, int size)

        {

            int bytesRead = 0;



            _connectionPermission.Assert();

            byte[] bytes = _connection.ReadRequestBytes(size);



            if (bytes != null && bytes.Length > 0)

            {

                bytesRead = bytes.Length;

                Buffer.BlockCopy(bytes, 0, buffer, 0, bytesRead);

            }



            return bytesRead;

        }



        public override void SendCalculatedContentLength(int contentLength)

        {

            if (!_headersSent)

            {

                _responseHeadersBuilder.Append("Content-Length: ");

                _responseHeadersBuilder.Append(contentLength.ToString(CultureInfo.InvariantCulture));

                _responseHeadersBuilder.Append("\r\n");

            }

        }



        public override void SendKnownResponseHeader(int index, string value)

        {

            if (_headersSent)

            {

                return;

            }



            switch (index)

            {

                case HeaderServer:

                case HeaderDate:

                case HeaderConnection:

                    // ignore these

                    return;

                case HeaderAcceptRanges:

                    // FIX: #14359

                    if (value != "bytes")

                    {

                        // use this header to detect when we're processing a static file

                        break;

                    }

                    _specialCaseStaticFileHeaders = true;

                    return;



                case HeaderExpires:

                case HeaderLastModified:

                    // FIX: #14359

                    if (!_specialCaseStaticFileHeaders)

                    {

                        // NOTE: Ignore these for static files. These are generated

                        //       by the StaticFileHandler, but they shouldn't be.

                        break;

                    }

                    return;





                // FIX: #12506

                case HeaderContentType:



                    string contentType = null;



                    if (value == "application/octet-stream")

                    {

                        // application/octet-stream is default for unknown so lets

                        // take a shot at determining the type.

                        // don't do this for other content-types as you are going to

                        // end up sending text/plain for endpoints that are handled by

                        // asp.net such as .aspx, .asmx, .axd, etc etc

                        contentType = CommonExtensions.GetContentType(_pathTranslated);

                    }

                    value = contentType ?? value;

                    break;

            }



            _responseHeadersBuilder.Append(GetKnownResponseHeaderName(index));

            _responseHeadersBuilder.Append(": ");

            _responseHeadersBuilder.Append(value);

            _responseHeadersBuilder.Append("\r\n");

        }



        public void SetResponseHeader(string name, string value)

        {

            _responseHeadersBuilder.Append(name);

            _responseHeadersBuilder.Append(": ");

            _responseHeadersBuilder.Append(value);

            _responseHeadersBuilder.Append("\r\n");

        }



        public override void SendResponseFromFile(string filename, long offset, long length)

        {

            if (length == 0)

            {

                return;

            }



            FileStream f = null;

            try

            {

                f = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);

                SendResponseFromFileStream(f, offset, length);

            }

            finally

            {

                if (f != null)

                {

                    f.Close();

                }

            }

        }



        public override void SendResponseFromFile(IntPtr handle, long offset, long length)

        {

            if (length == 0)

            {

                return;

            }



            using (var sfh = new SafeFileHandle(handle, false))

            {

                using (var f = new FileStream(sfh, FileAccess.Read))

                {

                    SendResponseFromFileStream(f, offset, length);

                }

            }

        }



        public override void SendResponseFromMemory(byte[] data, int length)

        {

            if (length > 0)

            {

                var bytes = new byte[length];



                Buffer.BlockCopy(data, 0, bytes, 0, length);

                _responseBodyBytes.Add(bytes);

            }

        }



        public override void SendStatus(int statusCode, string statusDescription)

        {

            _responseStatus = statusCode;

        }



        public override void SendUnknownResponseHeader(string name, string value)

        {

            if (_headersSent)

                return;



            _responseHeadersBuilder.Append(name);

            _responseHeadersBuilder.Append(": ");

            _responseHeadersBuilder.Append(value);

            _responseHeadersBuilder.Append("\r\n");

        }



        private bool IsBadPath()

        {

            if (_path.IndexOfAny(BadPathChars) >= 0)

            {

                return true;

            }



            if (CultureInfo.InvariantCulture.CompareInfo.IndexOf(_path, "..", CompareOptions.Ordinal) >= 0)

            {

                return true;

            }



            if (CultureInfo.InvariantCulture.CompareInfo.IndexOf(_path, "//", CompareOptions.Ordinal) >= 0)

            {

                return true;

            }



            return false;

        }



        private bool IsRequestForRestrictedDirectory()

        {

            String p = CultureInfo.InvariantCulture.TextInfo.ToLower(_path);



            if (_host.VirtualPath != "/")

            {

                p = p.Substring(_host.VirtualPath.Length);

            }



            foreach (String dir in RestrictedDirs)

            {

                if (p.StartsWith(dir, StringComparison.Ordinal))

                {

                    if (p.Length == dir.Length || p[dir.Length] == '/')

                    {

                        return true;

                    }

                }

            }



            return false;

        }



        private void ParseHeaders()

        {

            _knownRequestHeaders = new string[RequestHeaderMaximum];



            // construct unknown headers as array list of name1,value1,...

            var headers = new List<string>();



            for (int i = 1; i < _headerByteStrings.Count; i++)

            {

                string s = _headerByteStrings[i].GetString();



                int c = s.IndexOf(':');



                if (c >= 0)

                {

                    string name = s.Substring(0, c).Trim();

                    string value = s.Substring(c + 1).Trim();



                    // remember

                    int knownIndex = GetKnownRequestHeaderIndex(name);

                    if (knownIndex >= 0)

                    {

                        _knownRequestHeaders[knownIndex] = value;

                    }

                    else

                    {

                        headers.Add(name);

                        headers.Add(value);

                    }

                }

            }



            // copy to array unknown headers



            int n = headers.Count / 2;

            _unknownRequestHeaders = new string[n][];

            int j = 0;



            for (int i = 0; i < n; i++)

            {

                _unknownRequestHeaders[i] = new string[2];

                _unknownRequestHeaders[i][0] = headers[j++];

                _unknownRequestHeaders[i][1] = headers[j++];

            }



            // remember all raw headers as one string



            if (_headerByteStrings.Count > 1)

            {

                _allRawHeaders = Encoding.UTF8.GetString(_headerBytes, _startHeadersOffset,

                                                         _endHeadersOffset - _startHeadersOffset);

            }

            else

            {

                _allRawHeaders = String.Empty;

            }

        }



        private void ParsePostedContent()

        {

            _contentLength = 0;

            _bodyLength = 0;



            string contentLengthValue = _knownRequestHeaders[HeaderContentLength];

            if (contentLengthValue != null)

            {

                try

                {

                    _contentLength = Int32.Parse(contentLengthValue, CultureInfo.InvariantCulture);

                }

                // ReSharper disable EmptyGeneralCatchClause

                catch

                // ReSharper restore EmptyGeneralCatchClause

                {

                }

            }



            if (_headerBytes.Length > _endHeadersOffset)

            {

                _bodyLength = _headerBytes.Length - _endHeadersOffset;



                if (_bodyLength > _contentLength)

                {

                    _bodyLength = _contentLength; // don't read more than the content-length

                }



                if (_bodyLength > 0)

                {

                    _body = new byte[_bodyLength];

                    Buffer.BlockCopy(_headerBytes, _endHeadersOffset, _body, 0, _bodyLength);

                }

            }

        }



        private void ParseRequestLine()

        {

            ByteString requestLine = _headerByteStrings[0];

            ByteString[] elems = requestLine.Split(' ');



            if (elems == null || elems.Length < 2 || elems.Length > 3)

            {

                _connection.WriteErrorAndClose(400);

                return;

            }



            _verb = elems[0].GetString();



            ByteString urlBytes = elems[1];

            _url = urlBytes.GetString();



            _protocol = elems.Length == 3 ? elems[2].GetString() : "HTTP/1.0";



            // query string



            int iqs = urlBytes.IndexOf('?');

            _queryStringBytes = iqs > 0 ? urlBytes.Substring(iqs + 1).GetBytes() : new byte[0];



            iqs = _url.IndexOf('?');

            if (_url == "/" && !String.IsNullOrEmpty(_dfPage))

                _path = _dfPage;

            else if (iqs > 0)

            {

                _path = _url.Substring(0, iqs);

                _queryString = _url.Substring(iqs + 1);

            }

            else

            {

                _path = _url;

                _queryStringBytes = new byte[0];

            }



            // url-decode path



            if (_path.IndexOf('%') >= 0)

            {

                _path = HttpUtility.UrlDecode(_path, Encoding.UTF8);



                iqs = _url.IndexOf('?');

                if (iqs >= 0)

                {

                    _url = _path + _url.Substring(iqs);

                }

                else

                {

                    _url = _path;

                }

            }



            // path info



            int lastDot = _path.LastIndexOf('.');

            int lastSlh = _path.LastIndexOf('/');



            if (lastDot >= 0 && lastSlh >= 0 && lastDot < lastSlh)

            {

                int ipi = _path.IndexOf('/', lastDot);

                _filePath = _path.Substring(0, ipi);

                _pathInfo = _path.Substring(ipi);

            }

            else

            {

                _filePath = _path;

                _pathInfo = String.Empty;

            }



            _pathTranslated = MapPath(_filePath);



        }



        private void PrepareResponse()

        {

            _headersSent = false;

            _responseStatus = 200;

            _responseHeadersBuilder = new StringBuilder();

            _responseBodyBytes = new List<byte[]>();



            ProcessPlugins();

        }



        private bool ProcessDirectoryListingRequest()

        {

            if (_verb != "GET")

            {

                return false;

            }



            String dirPathTranslated = _pathTranslated;



            if (_pathInfo.Length > 0)

            {

                // directory path can never have pathInfo

                dirPathTranslated = MapPath(_path);

            }



            if (!Directory.Exists(dirPathTranslated))

            {

                return false;

            }



            // get all files and subdirs

            FileSystemInfo[] infos = null;

            try

            {

                infos = (new DirectoryInfo(dirPathTranslated)).GetFileSystemInfos();

            }

            // ReSharper disable EmptyGeneralCatchClause

            catch

            // ReSharper restore EmptyGeneralCatchClause

            {

            }



            // determine if parent is appropriate

            string parentPath = null;



            if (_path.Length > 1)

            {

                int i = _path.LastIndexOf('/', _path.Length - 2);



                parentPath = (i > 0) ? _path.Substring(0, i) : "/";

                if (!_host.IsVirtualPathInApp(parentPath))

                {

                    parentPath = null;

                }

            }



            _connection.WriteEntireResponseFromString(200, "Content-type: text/html; charset=utf-8\r\n",

                                                      Messages.FormatDirectoryListing(_path, parentPath, infos),

                                                      false);

            return true;

        }



        private bool ProcessDirectoryRequest()

        {

            String dirPathTranslated = _pathTranslated;



            if (_pathInfo.Length > 0)

            {

                // directory path can never have pathInfo

                dirPathTranslated = MapPath(_path);

            }



            if (!Directory.Exists(dirPathTranslated))

            {

                return false;

            }



            // have to redirect /foo to /foo/ to allow relative links to work

            if (!_path.EndsWith("/", StringComparison.Ordinal))

            {

                string newPath = _path + "/";

                string location = "Location: " + UrlEncodeRedirect(newPath) + "\r\n";

                string body = "<html><head><title>Object moved</title></head><body>\r\n" +

                              "<h2>Object moved to <a href='" + newPath + "'>here</a>.</h2>\r\n" +

                              "</body></html>\r\n";



                _connection.WriteEntireResponseFromString(302, location, body, false);

                return true;

            }



            // check for the default file

            foreach (string filename in DefaultFileNames)

            {

                string defaultFilePath = dirPathTranslated + "\\" + filename;



                if (File.Exists(defaultFilePath))

                {

                    // pretend the request is for the default file path

                    _path += filename;

                    _filePath = _path;

                    _url = (_queryString != null) ? (_path + "?" + _queryString) : _path;

                    _pathTranslated = defaultFilePath;

                    return false; // go through normal processing

                }

            }



            return false; // go through normal processing

        }



        private void ReadAllHeaders()

        {

            _headerBytes = null;



            do

            {

                if (!TryReadAllHeaders())

                {

                    // something bad happened

                    break;

                }

            } while (_endHeadersOffset < 0); // found \r\n\r\n



        }



        private void Reset()

        {

            _headerBytes = null;

            _startHeadersOffset = 0;

            _endHeadersOffset = 0;

            _headerByteStrings = null;



            _isClientScriptPath = false;



            _verb = null;

            _url = null;

            _protocol = null;



            _path = null;

            _filePath = null;

            _pathInfo = null;

            _pathTranslated = null;

            _queryString = null;

            _queryStringBytes = null;



            _contentLength = 0;

            _bodyLength = 0;

            _body = null;



            _allRawHeaders = null;

            _unknownRequestHeaders = null;

            _knownRequestHeaders = null;

            _specialCaseStaticFileHeaders = false;

        }



        private void SendResponseFromFileStream(Stream f, long offset, long length)

        {

            long fileSize = f.Length;



            if (length == -1)

            {

                length = fileSize - offset;

            }



            if (length == 0 || offset < 0 || length > fileSize - offset)

            {

                return;

            }



            if (offset > 0)

            {

                f.Seek(offset, SeekOrigin.Begin);

            }



            if (length <= MaxChunkLength)

            {

                var fileBytes = new byte[(int)length];

                int bytesRead = f.Read(fileBytes, 0, (int)length);

                SendResponseFromMemory(fileBytes, bytesRead);

            }

            else

            {

                var chunk = new byte[MaxChunkLength];

                var bytesRemaining = (int)length;



                while (bytesRemaining > 0)

                {

                    int bytesToRead = (bytesRemaining < MaxChunkLength) ? bytesRemaining : MaxChunkLength;

                    int bytesRead = f.Read(chunk, 0, bytesToRead);



                    SendResponseFromMemory(chunk, bytesRead);

                    bytesRemaining -= bytesRead;



                    // flush to release keep memory

                    if ((bytesRemaining > 0) && (bytesRead > 0))

                    {

                        FlushResponse(false);

                    }

                }

            }

        }



        private void SkipAllPostedContent()

        {

            if ((_contentLength > 0) && (_bodyLength < _contentLength))

            {

                byte[] buffer;

                for (int i = _contentLength - _bodyLength; i > 0; i -= buffer.Length)

                {

                    buffer = _connection.ReadRequestBytes(i);

                    if ((buffer == null) || (buffer.Length == 0))

                    {

                        return;

                    }

                }

            }

        }





        /// <summary>

        /// TODO: defer response until request is written

        /// </summary>

        /// <returns></returns>

        private bool TryParseRequest()

        {

            Reset();



            ReadAllHeaders();



            if (_headerBytes == null || _endHeadersOffset < 0 ||

                _headerByteStrings == null || _headerByteStrings.Count == 0)

            {

                _connection.WriteErrorAndClose(400);

                return false;

            }



            ParseRequestLine();



            // Check for bad path

            if (IsBadPath())

            {

                _connection.WriteErrorAndClose(400);

                return false;

            }



            // Check if the path is not well formed or is not for the current app

            if (!_host.IsVirtualPathInApp(_path, out _isClientScriptPath))

            {

                _connection.WriteErrorAndClose(404);

                return false;

            }



            ParseHeaders();



            ParsePostedContent();



            return true;

        }



        private bool TryReadAllHeaders()

        {

            // read the first packet (up to 32K)

            byte[] headerBytes = _connection.ReadRequestBytes(MaxHeaderBytes);



            if (headerBytes == null || headerBytes.Length == 0)

                return false;



            if (_headerBytes != null)

            {

                // previous partial read

                int len = headerBytes.Length + _headerBytes.Length;

                if (len > MaxHeaderBytes)

                    return false;



                var bytes = new byte[len];

                Buffer.BlockCopy(_headerBytes, 0, bytes, 0, _headerBytes.Length);

                Buffer.BlockCopy(headerBytes, 0, bytes, _headerBytes.Length, headerBytes.Length);

                _headerBytes = bytes;

            }

            else

            {

                _headerBytes = headerBytes;

            }



            // start parsing

            _startHeadersOffset = -1;

            _endHeadersOffset = -1;

            _headerByteStrings = new List<ByteString>();



            // find the end of headers

            var parser = new ByteParser(_headerBytes);



            for (; ; )

            {

                ByteString line = parser.ReadLine();



                if (line == null)

                {

                    break;

                }



                if (_startHeadersOffset < 0)

                {

                    _startHeadersOffset = parser.CurrentOffset;

                }



                if (line.IsEmpty)

                {

                    _endHeadersOffset = parser.CurrentOffset;

                    break;

                }



                _headerByteStrings.Add(line);

            }



            return true;

        }



        private static string UrlEncodeRedirect(string path)

        {

            // this method mimics the logic in HttpResponse.Redirect (which relies on internal methods)



            // count non-ascii characters

            byte[] bytes = Encoding.UTF8.GetBytes(path);

            int count = bytes.Length;

            int countNonAscii = 0;

            for (int i = 0; i < count; i++)

            {

                if ((bytes[i] & 0x80) != 0)

                {

                    countNonAscii++;

                }

            }



            // encode all non-ascii characters using UTF-8 %XX

            if (countNonAscii > 0)

            {

                // expand not 'safe' characters into %XX, spaces to +s

                var expandedBytes = new byte[count + countNonAscii * 2];

                int pos = 0;

                for (int i = 0; i < count; i++)

                {

                    byte b = bytes[i];



                    if ((b & 0x80) == 0)

                    {

                        expandedBytes[pos++] = b;

                    }

                    else

                    {

                        expandedBytes[pos++] = (byte)'%';

                        expandedBytes[pos++] = (byte)IntToHex[(b >> 4) & 0xf];

                        expandedBytes[pos++] = (byte)IntToHex[b & 0xf];

                    }

                }



                path = Encoding.ASCII.GetString(expandedBytes);

            }



            // encode spaces into %20

            if (path.IndexOf(' ') >= 0)

            {

                path = path.Replace(" ", "%20");

            }



            return path;

        }



        private void ProcessPlugins()

        {

            if (_connection.Plugins != null)

            {

                foreach (string pluginTypeName in _connection.Plugins)

                {

                    // #TODO: maybe keep plugins instantiated in the connection with reflected method cached?



                    Type pluginType = Type.GetType(pluginTypeName);

                    object plugin = Activator.CreateInstance(pluginType);

                    MethodInfo pluginMethod = plugin.GetType().GetMethod("ProcessRequest");

                    pluginMethod.Invoke(plugin, new object[] { this });

                    

                }

            }

        }

        #region Nested type: ByteParser



        internal class ByteParser

        {

            private readonly byte[] _bytes;



            private int _pos;



            public ByteParser(byte[] bytes)

            {

                _bytes = bytes;

                _pos = 0;

            }



            public int CurrentOffset

            {

                get { return _pos; }

            }



            public ByteString ReadLine()

            {

                ByteString line = null;



                for (int i = _pos; i < _bytes.Length; i++)

                {

                    if (_bytes[i] == (byte)'\n')

                    {

                        int len = i - _pos;

                        if (len > 0 && _bytes[i - 1] == (byte)'\r')

                        {

                            len--;

                        }



                        line = new ByteString(_bytes, _pos, len);

                        _pos = i + 1;

                        return line;

                    }

                }



                if (_pos < _bytes.Length)

                {

                    line = new ByteString(_bytes, _pos, _bytes.Length - _pos);

                }



                _pos = _bytes.Length;

                return line;

            }

        }



        #endregion



        #region Nested type: ByteString



        internal class ByteString

        {

            private readonly byte[] _bytes;



            private readonly int _length;



            private readonly int _offset;



            public ByteString(byte[] bytes, int offset, int length)

            {

                _bytes = bytes;

                _offset = offset;

                _length = length;

            }



            public byte[] Bytes

            {

                get { return _bytes; }

            }



            public bool IsEmpty

            {

                get { return (_bytes == null || _length == 0); }

            }



            public byte this[int index]

            {

                get { return _bytes[_offset + index]; }

            }



            public int Length

            {

                get { return _length; }

            }



            public int Offset

            {

                get { return _offset; }

            }



            public byte[] GetBytes()

            {

                var bytes = new byte[_length];

                if (_length > 0) Buffer.BlockCopy(_bytes, _offset, bytes, 0, _length);

                return bytes;

            }



            public string GetString(Encoding enc)

            {

                if (IsEmpty) return string.Empty;

                return enc.GetString(_bytes, _offset, _length);

            }



            public string GetString()

            {

                return GetString(Encoding.UTF8);

            }



            public int IndexOf(char ch)

            {

                return IndexOf(ch, 0);

            }



            public int IndexOf(char ch, int offset)

            {

                for (int i = offset; i < _length; i++)

                {

                    if (this[i] == (byte)ch) return i;

                }

                return -1;

            }



            public ByteString[] Split(char sep)

            {

                var list = new List<ByteString>();



                int pos = 0;

                while (pos < _length)

                {

                    int i = IndexOf(sep, pos);

                    if (i < 0)

                    {

                        break;

                    }



                    list.Add(Substring(pos, i - pos));

                    pos = i + 1;



                    while (this[pos] == (byte)sep && pos < _length)

                    {

                        pos++;

                    }

                }



                if (pos < _length)

                    list.Add(Substring(pos));



                return list.ToArray();

            }



            public ByteString Substring(int offset, int len)

            {

                return new ByteString(_bytes, _offset + offset, len);

            }



            public ByteString Substring(int offset)

            {

                return Substring(offset, _length - offset);

            }

        }



        #endregion

    }

}
Request
//  **********************************************************************************

//  CassiniDev - http://cassinidev.codeplex.com

// 

//  Copyright (c) 2010 Sky Sanders. All rights reserved.

//  

//  This source code is subject to terms and conditions of the Microsoft Public

//  License (Ms-PL). A copy of the license can be found in the license.txt file

//  included in this distribution.

//  

//  You must not remove this notice, or any other, from this software.

//  

//  **********************************************************************************



#region



using System;



#endregion



namespace SimpleWebServer

{

    ///<summary>

    ///</summary>

    public class RequestEventArgs : EventArgs

    {

        private readonly Guid _id;



        ///<summary>

        ///</summary>

        ///<param name="id"></param>

        ///<param name="requestLog"></param>

        ///<param name="responseLog"></param>

        public RequestEventArgs(Guid id)

        {

            _id = id;

        }



        ///<summary>

        ///</summary>

        public Guid Id

        {

            get { return _id; }

        }



        

    }

}
RequestEventArgs

代码出自:cassinidev.codeplex.com

你可能感兴趣的:(web服务器)