zoukankan      html  css  js  c++  java
  • 开发自定义的web IIS服务器 WebDev.WebHost 用控制台托起web服务

    上次写了一篇ASP.NET一个简易的WebServer,用控制台程序模拟IIS 托起web服务 看见有一朋友说在中文情况下返回乱码。我平时用的都是英文开发环境,即使涉及到中文也不是乱码,但是在公司中文的vs环境下也出现了乱码。一时半会不中的怎么解决。后来想起vs内嵌的那个服务器。。。。,于是乎拿来改写一下。

    先说说几个帮助类吧,我们中的http协议中请求头都是以\r\n\r\n结束的 在请求头中每个指令都是以\r\n分隔的, ByteParser就是用来分隔请求类容,再把一行的内容装到ByteString里面,ByteString主要作用是把字节转为字符。而Messages只是返回一些默认消息。Host就像原先的WebServer一样用来处理请求,Request是实现SimpleWorkerRequest的,用来真正处理用户请求。Server就是用来封装Host的暴露给调用者。至于NtlmAuth类没怎么明白好像是处理身份认证之类的东东。。。

    还是吧修改后的代码贴出来吧:

    ByteParser.cs
    namespace Microsoft.VisualStudio.WebHost
    {
        using System;
    
        internal sealed class ByteParser
        {
            private byte[] _bytes;
            private int _pos;
    
            internal ByteParser(byte[] bytes)
            {
                this._bytes = bytes;
                this._pos = 0;
            }
    
            internal ByteString ReadLine()
            {
                ByteString str = null;
                for (int i = this._pos; i < this._bytes.Length; i++)
                {
                    if (this._bytes[i] == 10)
                    {
                        int length = i - this._pos;
                        if ((length > 0) && (this._bytes[i - 1] == 13))
                        {
                            length--;
                        }
                        str = new ByteString(this._bytes, this._pos, length);
                        this._pos = i + 1;
                        return str;
                    }
                }
                if (this._pos < this._bytes.Length)
                {
                    str = new ByteString(this._bytes, this._pos, this._bytes.Length - this._pos);
                }
                this._pos = this._bytes.Length;
                return str;
            }
    
            internal int CurrentOffset
            {
                get
                {
                    return this._pos;
                }
            }
        }
    }
    ByteString.cs
    namespace Microsoft.VisualStudio.WebHost
    {
        using System;
        using System.Collections;
        using System.Reflection;
        using System.Text;
    
        internal sealed class ByteString
        {
            private byte[] _bytes;
            private int _length;
            private int _offset;
    
            public ByteString(byte[] bytes, int offset, int length)
            {
                this._bytes = bytes;
                if (((this._bytes != null) && (offset >= 0)) && ((length >= 0) && ((offset + length) <= this._bytes.Length)))
                {
                    this._offset = offset;
                    this._length = length;
                }
            }
    
            public byte[] GetBytes()
            {
                byte[] dst = new byte[this._length];
                if (this._length > 0)
                {
                    Buffer.BlockCopy(this._bytes, this._offset, dst, 0, this._length);
                }
                return dst;
            }
    
            public string GetString()
            {
                return this.GetString(Encoding.UTF8);
            }
    
            public string GetString(Encoding enc)
            {
                if (this.IsEmpty)
                {
                    return string.Empty;
                }
                return enc.GetString(this._bytes, this._offset, this._length);
            }
    
            public int IndexOf(char ch)
            {
                return this.IndexOf(ch, 0);
            }
    
            public int IndexOf(char ch, int offset)
            {
                for (int i = offset; i < this._length; i++)
                {
                    if (this[i] == ((byte) ch))
                    {
                        return i;
                    }
                }
                return -1;
            }
    
            public ByteString[] Split(char sep)
            {
                ArrayList list = new ArrayList();
                int offset = 0;
                while (offset < this._length)
                {
                    int index = this.IndexOf(sep, offset);
                    if (index < 0)
                    {
                        list.Add(this.Substring(offset));
                        break;
                    }
                    list.Add(this.Substring(offset, index - offset));
                    for (offset = index + 1; (offset < this._length) && (this[offset] == ((byte) sep)); offset++)
                    {
                    }
                }
                int count = list.Count;
                ByteString[] strArray = new ByteString[count];
                for (int i = 0; i < count; i++)
                {
                    strArray[i] = (ByteString) list[i];
                }
                return strArray;
            }
    
            public ByteString Substring(int offset)
            {
                return this.Substring(offset, this._length - offset);
            }
    
            public ByteString Substring(int offset, int len)
            {
                return new ByteString(this._bytes, this._offset + offset, len);
            }
    
            public byte[] Bytes
            {
                get
                {
                    return this._bytes;
                }
            }
    
            public bool IsEmpty
            {
                get
                {
                    if (this._bytes != null)
                    {
                        return (this._length == 0);
                    }
                    return true;
                }
            }
    
            public byte this[int index]
            {
                get
                {
                    return this._bytes[this._offset + index];
                }
            }
    
            public int Length
            {
                get
                {
                    return this._length;
                }
            }
    
            public int Offset
            {
                get
                {
                    return this._offset;
                }
            }
        }
    }
    Messages.cs
    namespace Microsoft.VisualStudio.WebHost
    {
        using System;
        using System.Globalization;
        using System.IO;
        using System.Text;
        using System.Web;
    
        internal class Messages
        {
            private const string _dirListingDirFormat = "{0,38:dddd, MMMM dd, yyyy hh:mm tt}        &lt;dir&gt; <A href=\"{1}/\">{2}</A>\r\n";
            private const string _dirListingFileFormat = "{0,38:dddd, MMMM dd, yyyy hh:mm tt} {1,12:n0} <A href=\"{2}\">{3}</A>\r\n";
            private const string _dirListingFormat1 = "<html>\r\n    <head>\r\n    <title>{0}</title>\r\n";
            private const string _dirListingFormat2 = "    </head>\r\n    <body bgcolor=\"white\">\r\n\r\n    <h2> <i>{0}</i> </h2></span>\r\n\r\n            <hr width=100% size=1 color=silver>\r\n\r\n<PRE>\r\n";
            private const string _dirListingParentFormat = "<A href=\"{0}\">[To Parent Directory]</A>\r\n\r\n";
            private static string _dirListingTail = ("</PRE>\r\n            <hr width=100% size=1 color=silver>\r\n\r\n              <b>{0}:</b>&nbsp;{1} " + VersionString + "\r\n\r\n            </font>\r\n\r\n    </body>\r\n</html>\r\n");
            private const string _httpErrorFormat1 = "<html>\r\n    <head>\r\n        <title>{0}</title>\r\n";
            private static string _httpErrorFormat2 = ("    </head>\r\n    <body bgcolor=\"white\">\r\n\r\n            <span><h1>{0}<hr width=100% size=1 color=silver></h1>\r\n\r\n            <h2> <i>{1}</i> </h2></span>\r\n\r\n            <hr width=100% size=1 color=silver>\r\n\r\n            <b>{2}:</b>&nbsp;{3} " + VersionString + "\r\n\r\n            </font>\r\n\r\n    </body>\r\n</html>\r\n");
            private const string _httpStyle = "        <style>\r\n        \tbody {font-family:\"Verdana\";font-weight:normal;font-size: 8pt;color:black;} \r\n        \tp {font-family:\"Verdana\";font-weight:normal;color:black;margin-top: -5px}\r\n        \tb {font-family:\"Verdana\";font-weight:bold;color:black;margin-top: -5px}\r\n        \th1 { font-family:\"Verdana\";font-weight:normal;font-size:18pt;color:red }\r\n        \th2 { font-family:\"Verdana\";font-weight:normal;font-size:14pt;color:maroon }\r\n        \tpre {font-family:\"Lucida Console\";font-size: 8pt}\r\n        \t.marker {font-weight: bold; color: black;text-decoration: none;}\r\n        \t.version {color: gray;}\r\n        \t.error {margin-bottom: 10px;}\r\n        \t.expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }\r\n        </style>\r\n";
            public static string VersionString = GetVersionString();
    
            public static string FormatDirectoryListing(string dirPath, string parentPath, FileSystemInfo[] elements)
            {
                StringBuilder builder = new StringBuilder();
                string str = string.Format("Directory Listing -- {0}",  dirPath );
                string str2 = "Version Information";
                string str3 = "ASP.NET Development Server";
                string str4 = string.Format(CultureInfo.InvariantCulture, _dirListingTail, new object[] { str2, str3 });
    
                builder.Append(string.Format(CultureInfo.InvariantCulture, "<html>\r\n    <head>\r\n    <title>{0}</title>\r\n", new object[] { str }));
                builder.Append("        <style>\r\n        \tbody {font-family:\"Verdana\";font-weight:normal;font-size: 8pt;color:black;} \r\n        \tp {font-family:\"Verdana\";font-weight:normal;color:black;margin-top: -5px}\r\n        \tb {font-family:\"Verdana\";font-weight:bold;color:black;margin-top: -5px}\r\n        \th1 { font-family:\"Verdana\";font-weight:normal;font-size:18pt;color:red }\r\n        \th2 { font-family:\"Verdana\";font-weight:normal;font-size:14pt;color:maroon }\r\n        \tpre {font-family:\"Lucida Console\";font-size: 8pt}\r\n        \t.marker {font-weight: bold; color: black;text-decoration: none;}\r\n        \t.version {color: gray;}\r\n        \t.error {margin-bottom: 10px;}\r\n        \t.expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }\r\n        </style>\r\n");
                builder.Append(string.Format(CultureInfo.InvariantCulture, "    </head>\r\n    <body bgcolor=\"white\">\r\n\r\n    <h2> <i>{0}</i> </h2></span>\r\n\r\n            <hr width=100% size=1 color=silver>\r\n\r\n<PRE>\r\n", new object[] { str }));
                if (parentPath != null)
                {
                    if (!parentPath.EndsWith("/", StringComparison.Ordinal))
                    {
                        parentPath = parentPath + "/";
                    }
                    builder.Append(string.Format(CultureInfo.InvariantCulture, "<A href=\"{0}\">[To Parent Directory]</A>\r\n\r\n", new object[] { parentPath }));
                }
                if (elements != null)
                {
                    for (int i = 0; i < elements.Length; i++)
                    {
                        if (elements[i] is FileInfo)
                        {
                            FileInfo info = (FileInfo) elements[i];
                            builder.Append(string.Format(CultureInfo.InvariantCulture, "{0,38:dddd, MMMM dd, yyyy hh:mm tt} {1,12:n0} <A href=\"{2}\">{3}</A>\r\n", new object[] { info.LastWriteTime, info.Length, info.Name, info.Name }));
                        }
                        else if (elements[i] is DirectoryInfo)
                        {
                            DirectoryInfo info2 = (DirectoryInfo) elements[i];
                            builder.Append(string.Format(CultureInfo.InvariantCulture, "{0,38:dddd, MMMM dd, yyyy hh:mm tt}        &lt;dir&gt; <A href=\"{1}/\">{2}</A>\r\n", new object[] { info2.LastWriteTime, info2.Name, info2.Name }));
                        }
                    }
                }
                builder.Append(str4);
                return builder.ToString();
            }
    
            public static string FormatErrorMessageBody(int statusCode, string appName)
            {
                string statusDescription = HttpWorkerRequest.GetStatusDescription(statusCode);
                string str2 = string.Format("Server Error in '{0}' Application.", appName);
                string str3 = string.Format("HTTP Error {0} - {1}.", statusCode, statusDescription);
                string str4 = "Version Information";
                string str5 = "ASP.NET Development Server";
                return (string.Format(CultureInfo.InvariantCulture, "<html>\r\n    <head>\r\n        <title>{0}</title>\r\n", new object[] { statusDescription }) + "        <style>\r\n        \tbody {font-family:\"Verdana\";font-weight:normal;font-size: 8pt;color:black;} \r\n        \tp {font-family:\"Verdana\";font-weight:normal;color:black;margin-top: -5px}\r\n        \tb {font-family:\"Verdana\";font-weight:bold;color:black;margin-top: -5px}\r\n        \th1 { font-family:\"Verdana\";font-weight:normal;font-size:18pt;color:red }\r\n        \th2 { font-family:\"Verdana\";font-weight:normal;font-size:14pt;color:maroon }\r\n        \tpre {font-family:\"Lucida Console\";font-size: 8pt}\r\n        \t.marker {font-weight: bold; color: black;text-decoration: none;}\r\n        \t.version {color: gray;}\r\n        \t.error {margin-bottom: 10px;}\r\n        \t.expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }\r\n        </style>\r\n" + string.Format(CultureInfo.InvariantCulture, _httpErrorFormat2, new object[] { str2, str3, str4, str5 }));
            }
    
            private static string GetVersionString()
            {
                return "10.0.0.0";
            }
        }
    }
    NtlmAuth.cs
    namespace Microsoft.VisualStudio.WebHost
    {
        using System;
        using System.Runtime.InteropServices;
        using System.Security;
        using System.Security.Principal;
    
        [SuppressUnmanagedCodeSecurity]
        internal sealed class NtlmAuth : IDisposable
        {
            private string _blob;
            private bool _completed;
            private SecHandle _credentialsHandle;
            private bool _credentialsHandleAcquired;
            private SecBuffer _inputBuffer;
            private SecBufferDesc _inputBufferDesc;
            private SecBuffer _outputBuffer;
            private SecBufferDesc _outputBufferDesc;
            private SecHandle _securityContext;
            private bool _securityContextAcquired;
            private uint _securityContextAttributes;
            private SecurityIdentifier _sid;
            private long _timestamp;
            private const int ISC_REQ_ALLOCATE_MEMORY = 0x100;
            private const int ISC_REQ_CONFIDENTIALITY = 0x10;
            private const int ISC_REQ_DELEGATE = 1;
            private const int ISC_REQ_MUTUAL_AUTH = 2;
            private const int ISC_REQ_PROMPT_FOR_CREDS = 0x40;
            private const int ISC_REQ_REPLAY_DETECT = 4;
            private const int ISC_REQ_SEQUENCE_DETECT = 8;
            private const int ISC_REQ_STANDARD_FLAGS = 20;
            private const int ISC_REQ_USE_SESSION_KEY = 0x20;
            private const int ISC_REQ_USE_SUPPLIED_CREDS = 0x80;
            private const int SEC_E_OK = 0;
            private const int SEC_I_COMPLETE_AND_CONTINUE = 0x90314;
            private const int SEC_I_COMPLETE_NEEDED = 0x90313;
            private const int SEC_I_CONTINUE_NEEDED = 0x90312;
            private const int SECBUFFER_DATA = 1;
            private const int SECBUFFER_EMPTY = 0;
            private const int SECBUFFER_TOKEN = 2;
            private const int SECBUFFER_VERSION = 0;
            private const int SECPKG_CRED_INBOUND = 1;
            private const int SECURITY_NETWORK_DREP = 0;
    
            public NtlmAuth()
            {
                if (AcquireCredentialsHandle(null, "NTLM", 1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref this._credentialsHandle, ref this._timestamp) != 0)
                {
                    throw new InvalidOperationException();
                }
                this._credentialsHandleAcquired = true;
            }
    
            [DllImport("SECUR32.DLL", CharSet=CharSet.Unicode)]
            private 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)]
            private static extern int AcquireCredentialsHandle(string pszPrincipal, string pszPackage, uint fCredentialUse, IntPtr pvLogonID, IntPtr pAuthData, IntPtr pGetKeyFn, IntPtr pvGetKeyArgument, ref SecHandle phCredential, ref long ptsExpiry);
            public unsafe bool Authenticate(string blobString)
            {
                this._blob = null;
                byte[] buffer = Convert.FromBase64String(blobString);
                byte[] inArray = new byte[0x4000];
                fixed (SecHandle* voidRef = &this._securityContext)
                {
                    fixed (SecBuffer* voidRef2 = &this._inputBuffer)
                    {
                        fixed (SecBuffer* voidRef3 = &this._outputBuffer)
                        {
                            fixed (void* voidRef4 = buffer)
                            {
                                fixed (void* voidRef5 = inArray)
                                {
                                    IntPtr zero = IntPtr.Zero;
                                    if (this._securityContextAcquired)
                                    {
                                        zero = (IntPtr)voidRef;
                                    }
                                    this._inputBufferDesc.ulVersion = 0;
                                    this._inputBufferDesc.cBuffers = 1;
                                    this._inputBufferDesc.pBuffers = (IntPtr)voidRef2;
                                    this._inputBuffer.cbBuffer = (uint)buffer.Length;
                                    this._inputBuffer.BufferType = 2;
                                    this._inputBuffer.pvBuffer = (IntPtr)voidRef4;
                                    this._outputBufferDesc.ulVersion = 0;
                                    this._outputBufferDesc.cBuffers = 1;
                                    this._outputBufferDesc.pBuffers = (IntPtr)voidRef3;
                                    this._outputBuffer.cbBuffer = (uint)inArray.Length;
                                    this._outputBuffer.BufferType = 2;
                                    this._outputBuffer.pvBuffer = (IntPtr)voidRef5;
                                    int num = AcceptSecurityContext(ref this._credentialsHandle, zero, ref this._inputBufferDesc, 20, 0, ref this._securityContext, ref this._outputBufferDesc, ref this._securityContextAttributes, ref this._timestamp);
                                    if (num == 0x90312)
                                    {
                                        this._securityContextAcquired = true;
                                        this._blob = Convert.ToBase64String(inArray, 0, (int)this._outputBuffer.cbBuffer);
                                    }
                                    else
                                    {
                                        if (num != 0)
                                        {
                                            return false;
                                        }
                                        IntPtr phToken = IntPtr.Zero;
                                        if (QuerySecurityContextToken(ref this._securityContext, ref phToken) != 0)
                                        {
                                            return false;
                                        }
                                        try
                                        {
                                            using (WindowsIdentity identity = new WindowsIdentity(phToken))
                                            {
                                                this._sid = identity.User;
                                            }
                                        }
                                        finally
                                        {
                                            CloseHandle(phToken);
                                        }
                                        this._completed = true;
                                    }
                                }
                            }
                        }
                    }
                }
                return true;
            }
    
    
            [DllImport("KERNEL32.DLL", CharSet=CharSet.Unicode)]
            private static extern int CloseHandle(IntPtr phToken);
            [DllImport("SECUR32.DLL", CharSet=CharSet.Unicode)]
            private static extern int DeleteSecurityContext(ref SecHandle phContext);
            ~NtlmAuth()
            {
                this.FreeUnmanagedResources();
            }
    
            [DllImport("SECUR32.DLL", CharSet=CharSet.Unicode)]
            private static extern int FreeCredentialsHandle(ref SecHandle phCredential);
            private void FreeUnmanagedResources()
            {
                if (this._securityContextAcquired)
                {
                    DeleteSecurityContext(ref this._securityContext);
                }
                if (this._credentialsHandleAcquired)
                {
                    FreeCredentialsHandle(ref this._credentialsHandle);
                }
            }
    
            [DllImport("SECUR32.DLL", CharSet=CharSet.Unicode)]
            private static extern int QuerySecurityContextToken(ref SecHandle phContext, ref IntPtr phToken);
            void IDisposable.Dispose()
            {
                this.FreeUnmanagedResources();
                GC.SuppressFinalize(this);
            }
    
            public string Blob
            {
                get
                {
                    return this._blob;
                }
            }
    
            public bool Completed
            {
                get
                {
                    return this._completed;
                }
            }
    
            public SecurityIdentifier SID
            {
                get
                {
                    return this._sid;
                }
            }
    
            [StructLayout(LayoutKind.Sequential)]
            private struct SecBuffer
            {
                public uint cbBuffer;
                public uint BufferType;
                public IntPtr pvBuffer;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            private struct SecBufferDesc
            {
                public uint ulVersion;
                public uint cBuffers;
                public IntPtr pBuffers;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            private struct SecHandle
            {
                public IntPtr dwLower;
                public IntPtr dwUpper;
            }
        }
    }
    Host.cs
    namespace Microsoft.VisualStudio.WebHost
    {
        using System;
        using System.Globalization;
        using System.Runtime.CompilerServices;
        using System.Runtime.InteropServices;
        using System.Security.Permissions;
        using System.Security.Principal;
        using System.Threading;
        using System.Web;
        using System.Web.Hosting;
    
        internal sealed class Host : MarshalByRefObject, IRegisteredObject
        {
            private bool _disableDirectoryListing;
            private string _installPath;
            private string _lowerCasedClientScriptPathWithTrailingSlash;
            private string _lowerCasedVirtualPath;
            private string _lowerCasedVirtualPathWithTrailingSlash;
            //private volatile int _pendingCallsCount;
            private  int _pendingCallsCount;
            private string _physicalClientScriptPath;
            private string _physicalPath;
            private int _port;
            private bool _requireAuthentication;
            private Server _server;
            private string _virtualPath;
    
            public Host()
            {
                HostingEnvironment.RegisterObject(this);
            }
    
            private void AddPendingCall()
            {
                Interlocked.Increment(ref this._pendingCallsCount);
            }
    
            public void Configure(Server server, int port, string virtualPath, string physicalPath, bool requireAuthentication)
            {
                this.Configure(server, port, virtualPath, physicalPath, requireAuthentication, false);
            }
    
            public void Configure(Server server, int port, string virtualPath, string physicalPath, bool requireAuthentication, bool disableDirectoryListing)
            {
                this._server = server;
                this._port = port;
                this._installPath = null;
                this._virtualPath = virtualPath;
                this._requireAuthentication = requireAuthentication;
                this._disableDirectoryListing = disableDirectoryListing;
                this._lowerCasedVirtualPath = CultureInfo.InvariantCulture.TextInfo.ToLower(this._virtualPath);
                this._lowerCasedVirtualPathWithTrailingSlash = virtualPath.EndsWith("/", StringComparison.Ordinal) ? virtualPath : (virtualPath + "/");
                this._lowerCasedVirtualPathWithTrailingSlash = CultureInfo.InvariantCulture.TextInfo.ToLower(this._lowerCasedVirtualPathWithTrailingSlash);
                this._physicalPath = physicalPath;
                this._physicalClientScriptPath = HttpRuntime.AspClientScriptPhysicalPath + @"\";
                this._lowerCasedClientScriptPathWithTrailingSlash = CultureInfo.InvariantCulture.TextInfo.ToLower(HttpRuntime.AspClientScriptVirtualPath + "/");
            }
    
            public SecurityIdentifier GetProcessSID()
            {
                using (WindowsIdentity identity = new WindowsIdentity(this._server.GetProcessToken()))
                {
                    return identity.User;
                }
            }
    
            public IntPtr GetProcessToken()
            {
                new SecurityPermission(PermissionState.Unrestricted).Assert();
                return this._server.GetProcessToken();
            }
    
            public string GetProcessUser()
            {
                return this._server.GetProcessUser();
            }
    
            public override object InitializeLifetimeService()
            {
                return null;
            }
    
            public bool IsVirtualPathAppPath(string path)
            {
                if (path == null)
                {
                    return false;
                }
                path = CultureInfo.InvariantCulture.TextInfo.ToLower(path);
                if (!(path == this._lowerCasedVirtualPath))
                {
                    return (path == this._lowerCasedVirtualPathWithTrailingSlash);
                }
                return true;
            }
    
            public bool IsVirtualPathInApp(string path)
            {
                bool flag;
                return this.IsVirtualPathInApp(path, out flag);
            }
    
            public bool IsVirtualPathInApp(string path, out bool isClientScriptPath)
            {
                isClientScriptPath = false;
                if (path != null)
                {
                    path = CultureInfo.InvariantCulture.TextInfo.ToLower(path);
                    if ((this._virtualPath == "/") && path.StartsWith("/", StringComparison.Ordinal))
                    {
                        if (path.StartsWith(this._lowerCasedClientScriptPathWithTrailingSlash, StringComparison.Ordinal))
                        {
                            isClientScriptPath = true;
                        }
                        return true;
                    }
                    if (path.StartsWith(this._lowerCasedVirtualPathWithTrailingSlash, StringComparison.Ordinal))
                    {
                        return true;
                    }
                    if (path == this._lowerCasedVirtualPath)
                    {
                        return true;
                    }
                    if (path.StartsWith(this._lowerCasedClientScriptPathWithTrailingSlash, StringComparison.Ordinal))
                    {
                        isClientScriptPath = true;
                        return true;
                    }
                }
                return false;
            }
    
            public void ProcessRequest(Connection conn)
            {
                this.AddPendingCall();
                try
                {
                    new Request(this, conn).Process();
                }
                finally
                {
                    this.RemovePendingCall();
                }
            }
    
            private void RemovePendingCall()
            {
                Interlocked.Decrement(ref this._pendingCallsCount);
            }
    
            [SecurityPermission(SecurityAction.Assert, Unrestricted=true)]
            public void Shutdown()
            {
                HostingEnvironment.InitiateShutdown();
            }
    
            void IRegisteredObject.Stop(bool immediate)
            {
                if (this._server != null)
                {
                    this._server.HostStopped();
                }
                this.WaitForPendingCallsToFinish();
                HostingEnvironment.UnregisterObject(this);
            }
    
            private void WaitForPendingCallsToFinish()
            {
                while (this._pendingCallsCount > 0)
                {
                    Thread.Sleep(250);
                }
            }
    
            public bool DisableDirectoryListing
            {
                get
                {
                    return this._disableDirectoryListing;
                }
            }
    
            public string InstallPath
            {
                get
                {
                    return this._installPath;
                }
            }
    
            public string NormalizedClientScriptPath
            {
                get
                {
                    return this._lowerCasedClientScriptPathWithTrailingSlash;
                }
            }
    
            public string NormalizedVirtualPath
            {
                get
                {
                    return this._lowerCasedVirtualPathWithTrailingSlash;
                }
            }
    
            public string PhysicalClientScriptPath
            {
                get
                {
                    return this._physicalClientScriptPath;
                }
            }
    
            public string PhysicalPath
            {
                get
                {
                    return this._physicalPath;
                }
            }
    
            public int Port
            {
                get
                {
                    return this._port;
                }
            }
    
            public bool RequireAuthentication
            {
                get
                {
                    return this._requireAuthentication;
                }
            }
    
            public string VirtualPath
            {
                get
                {
                    return this._virtualPath;
                }
            }
        }
    }
    Connection.cs
    namespace Microsoft.VisualStudio.WebHost
    {
        using System;
        using System.Globalization;
        using System.IO;
        using System.Net;
        using System.Net.Sockets;
        using System.Text;
        using System.Web;
    
        internal sealed class Connection : MarshalByRefObject
        {
            private static string _defaultLoalhostIP;
            private static string _localServerIP;
            private Server _server;
            private Socket _socket;
    
            internal Connection(Server server, Socket socket)
            {
                this._server = server;
                this._socket = socket;
            }
    
            internal void Close()
            {
                try
                {
                    this._socket.Shutdown(SocketShutdown.Both);
                    this._socket.Close();
                }
                catch
                {
                }
                finally
                {
                    this._socket = null;
                }
            }
    
            private string GetErrorResponseBody(int statusCode, string message)
            {
                string str = Messages.FormatErrorMessageBody(statusCode, this._server.VirtualPath);
                if ((message != null) && (message.Length > 0))
                {
                    str = str + "\r\n<!--\r\n" + message + "\r\n-->";
                }
                return str;
            }
    
            public override object InitializeLifetimeService()
            {
                return null;
            }
    
            private static string MakeContentTypeHeader(string fileName)
            {
                string str = null;
                FileInfo info = new FileInfo(fileName);
                switch (info.Extension.ToLowerInvariant())
                {
                    case ".bmp":
                        str = "image/bmp";
                        break;
    
                    case ".css":
                        str = "text/css";
                        break;
    
                    case ".gif":
                        str = "image/gif";
                        break;
    
                    case ".ico":
                        str = "image/x-icon";
                        break;
    
                    case ".htm":
                    case ".html":
                        str = "text/html";
                        break;
    
                    case ".jpe":
                    case ".jpeg":
                    case ".jpg":
                        str = "image/jpeg";
                        break;
    
                    case ".js":
                        str = "application/x-javascript";
                        break;
                }
                if (str == null)
                {
                    return null;
                }
                return ("Content-Type: " + str + "\r\n");
            }
    
            private static string MakeResponseHeaders(int statusCode, string moreHeaders, int contentLength, bool keepAlive)
            {
                StringBuilder builder = new StringBuilder();
                builder.Append(string.Concat(new object[] { "HTTP/1.1 ", statusCode, " ", HttpWorkerRequest.GetStatusDescription(statusCode), "\r\n" }));
                builder.Append("Server: ASP.NET Development Server/" + Messages.VersionString + "\r\n");
                builder.Append("Date: " + DateTime.Now.ToUniversalTime().ToString("R", DateTimeFormatInfo.InvariantInfo) + "\r\n");
                if (contentLength >= 0)
                {
                    builder.Append("Content-Length: " + contentLength + "\r\n");
                }
                if (moreHeaders != null)
                {
                    builder.Append(moreHeaders);
                }
                if (!keepAlive)
                {
                    builder.Append("Connection: Close\r\n");
                }
                builder.Append("\r\n");
                return builder.ToString();
            }
    
            internal byte[] ReadRequestBytes(int maxBytes)
            {
                try
                {
                    if (this.WaitForRequestBytes() == 0)
                    {
                        return null;
                    }
                    int available = this._socket.Available;
                    if (available > maxBytes)
                    {
                        available = maxBytes;
                    }
                    int count = 0;
                    byte[] buffer = new byte[available];
                    if (available > 0)
                    {
                        count = this._socket.Receive(buffer, 0, available, SocketFlags.None);
                    }
                    if (count < available)
                    {
                        byte[] dst = new byte[count];
                        if (count > 0)
                        {
                            Buffer.BlockCopy(buffer, 0, dst, 0, count);
                        }
                        buffer = dst;
                    }
                    return buffer;
                }
                catch
                {
                    return null;
                }
            }
    
            internal int WaitForRequestBytes()
            {
                int available = 0;
                try
                {
                    if (this._socket.Available == 0)
                    {
                        this._socket.Poll(0x186a0, SelectMode.SelectRead);
                        if ((this._socket.Available == 0) && this._socket.Connected)
                        {
                            this._socket.Poll(0x1c9c380, SelectMode.SelectRead);
                        }
                    }
                    available = this._socket.Available;
                }
                catch
                {
                }
                return available;
            }
    
            internal void Write100Continue()
            {
                this.WriteEntireResponseFromString(100, null, null, true);
            }
    
            internal void WriteBody(byte[] data, int offset, int length)
            {
                try
                {
                    this._socket.Send(data, offset, length, SocketFlags.None);
                }
                catch (SocketException)
                {
                }
            }
    
            internal void WriteEntireResponseFromFile(string fileName, bool keepAlive)
            {
                if (!System.IO.File.Exists(fileName))
                {
                    this.WriteErrorAndClose(0x194);
                }
                else
                {
                    string moreHeaders = MakeContentTypeHeader(fileName);
                    if (moreHeaders == null)
                    {
                        this.WriteErrorAndClose(0x193);
                    }
                    else
                    {
                        bool flag = false;
                        FileStream stream = null;
                        try
                        {
                            stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                            int length = (int) stream.Length;
                            byte[] buffer = new byte[length];
                            int contentLength = stream.Read(buffer, 0, length);
                            string s = MakeResponseHeaders(200, moreHeaders, contentLength, keepAlive);
                            this._socket.Send(Encoding.UTF8.GetBytes(s));
                            this._socket.Send(buffer, 0, contentLength, SocketFlags.None);
                            flag = true;
                        }
                        catch (SocketException)
                        {
                        }
                        finally
                        {
                            if (!keepAlive || !flag)
                            {
                                this.Close();
                            }
                            if (stream != null)
                            {
                                stream.Close();
                            }
                        }
                    }
                }
            }
    
            internal void WriteEntireResponseFromString(int statusCode, string extraHeaders, string body, bool keepAlive)
            {
                try
                {
                    int contentLength = (body != null) ? Encoding.UTF8.GetByteCount(body) : 0;
                    string str = MakeResponseHeaders(statusCode, extraHeaders, contentLength, keepAlive);
                    this._socket.Send(Encoding.UTF8.GetBytes(str + body));
                }
                catch (SocketException)
                {
                }
                finally
                {
                    if (!keepAlive)
                    {
                        this.Close();
                    }
                }
            }
    
            internal void WriteErrorAndClose(int statusCode)
            {
                this.WriteErrorAndClose(statusCode, null);
            }
    
            internal void WriteErrorAndClose(int statusCode, string message)
            {
                this.WriteEntireResponseFromString(statusCode, "Content-type:text/html;charset=utf-8\r\n", this.GetErrorResponseBody(statusCode, message), false);
            }
    
            internal void WriteErrorWithExtraHeadersAndKeepAlive(int statusCode, string extraHeaders)
            {
                this.WriteEntireResponseFromString(statusCode, extraHeaders, this.GetErrorResponseBody(statusCode, null), true);
            }
    
            internal void WriteHeaders(int statusCode, string extraHeaders)
            {
                string s = MakeResponseHeaders(statusCode, extraHeaders, -1, false);
                try
                {
                    this._socket.Send(Encoding.UTF8.GetBytes(s));
                }
                catch (SocketException)
                {
                }
            }
    
            internal bool Connected
            {
                get
                {
                    return this._socket.Connected;
                }
            }
    
            private string DefaultLocalHostIP
            {
                get
                {
                    if (string.IsNullOrEmpty(_defaultLoalhostIP))
                    {
                        if (!Socket.OSSupportsIPv4 && Socket.OSSupportsIPv6)
                        {
                            _defaultLoalhostIP = "::1";
                        }
                        else
                        {
                            _defaultLoalhostIP = "127.0.0.1";
                        }
                    }
                    return _defaultLoalhostIP;
                }
            }
    
            internal bool IsLocal
            {
                get
                {
                    string remoteIP = this.RemoteIP;
                    if (string.IsNullOrEmpty(remoteIP))
                    {
                        return false;
                    }
                    if ((!remoteIP.Equals("127.0.0.1") && !remoteIP.Equals("::1")) && !remoteIP.Equals("::ffff:127.0.0.1"))
                    {
                        return LocalServerIP.Equals(remoteIP);
                    }
                    return true;
                }
            }
    
            internal string LocalIP
            {
                get
                {
                    IPEndPoint localEndPoint = (IPEndPoint) this._socket.LocalEndPoint;
                    if ((localEndPoint != null) && (localEndPoint.Address != null))
                    {
                        return localEndPoint.Address.ToString();
                    }
                    return this.DefaultLocalHostIP;
                }
            }
    
            private static string LocalServerIP
            {
                get
                {
                    if (_localServerIP == null)
                    {
                        _localServerIP = Dns.GetHostEntry(Environment.MachineName).AddressList[0].ToString();
                    }
                    return _localServerIP;
                }
            }
    
            internal string RemoteIP
            {
                get
                {
                    IPEndPoint remoteEndPoint = (IPEndPoint) this._socket.RemoteEndPoint;
                    if ((remoteEndPoint != null) && (remoteEndPoint.Address != null))
                    {
                        return remoteEndPoint.Address.ToString();
                    }
                    return "";
                }
            }
        }
    }
    Request.cs
    namespace Microsoft.VisualStudio.WebHost
    {
        using Microsoft.Win32.SafeHandles;
        using System;
        using System.Collections;
        using System.Globalization;
        using System.IO;
        using System.Security;
        using System.Security.Permissions;
        using System.Text;
        using System.Web;
        using System.Web.Hosting;
    
        internal sealed class Request : SimpleWorkerRequest
        {
            private string _allRawHeaders;
            private Connection _connection;
            private IStackWalk _connectionPermission;
            private int _contentLength;
            private int _endHeadersOffset;
            private string _filePath;
            private byte[] _headerBytes;
            private ArrayList _headerByteStrings;
            private bool _headersSent;
            private Host _host;
            private bool _isClientScriptPath;
            private string[] _knownRequestHeaders;
            private string _path;
            private string _pathInfo;
            private string _pathTranslated;
            private byte[] _preloadedContent;
            private int _preloadedContentLength;
            private string _prot;
            private string _queryString;
            private byte[] _queryStringBytes;
            private ArrayList _responseBodyBytes;
            private StringBuilder _responseHeadersBuilder;
            private int _responseStatus;
            private bool _specialCaseStaticFileHeaders;
            private int _startHeadersOffset;
            private string[][] _unknownRequestHeaders;
            private string _url;
            private string _verb;
            private static char[] badPathChars = new char[] { '%', '>', '<', ':', '\\' };
            private static string[] defaultFileNames = new string[] { "default.aspx", "default.htm", "default.html" };
            private static char[] IntToHex = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
            private const int MaxChunkLength = 0x10000;
            private const int maxHeaderBytes = 0x8000;
            private static string[] restrictedDirs = new string[] { "/bin", "/app_browsers", "/app_code", "/app_data", "/app_localresources", "/app_globalresources", "/app_webreferences" };
    
            public Request(Host host, Connection connection) : base(string.Empty, string.Empty, null)
            {
                this._connectionPermission = new PermissionSet(PermissionState.Unrestricted);
                this._host = host;
                this._connection = connection;
            }
    
            public override void CloseConnection()
            {
                this._connectionPermission.Assert();
                this._connection.Close();
            }
    
            public override void EndOfRequest()
            {
            }
    
            public override void FlushResponse(bool finalFlush)
            {
                if ((((this._responseStatus != 0x194) || this._headersSent) || (!finalFlush || (this._verb != "GET"))) || !this.ProcessDirectoryListingRequest())
                {
                    this._connectionPermission.Assert();
                    if (!this._headersSent)
                    {
                        this._connection.WriteHeaders(this._responseStatus, this._responseHeadersBuilder.ToString());
                        this._headersSent = true;
                    }
                    for (int i = 0; i < this._responseBodyBytes.Count; i++)
                    {
                        byte[] data = (byte[]) this._responseBodyBytes[i];
                        this._connection.WriteBody(data, 0, data.Length);
                    }
                    this._responseBodyBytes = new ArrayList();
                    if (finalFlush)
                    {
                        this._connection.Close();
                    }
                }
            }
    
            public override string GetAppPath()
            {
                return this._host.VirtualPath;
            }
    
            public override string GetAppPathTranslated()
            {
                return this._host.PhysicalPath;
            }
    
            public override string GetFilePath()
            {
                return this._filePath;
            }
    
            public override string GetFilePathTranslated()
            {
                return this._pathTranslated;
            }
    
            public override string GetHttpVerbName()
            {
                return this._verb;
            }
    
            public override string GetHttpVersion()
            {
                return this._prot;
            }
    
            public override string GetKnownRequestHeader(int index)
            {
                return this._knownRequestHeaders[index];
            }
    
            public override string GetLocalAddress()
            {
                this._connectionPermission.Assert();
                return this._connection.LocalIP;
            }
    
            public override int GetLocalPort()
            {
                return this._host.Port;
            }
    
            public override string GetPathInfo()
            {
                return this._pathInfo;
            }
    
            public override byte[] GetPreloadedEntityBody()
            {
                return this._preloadedContent;
            }
    
            public override string GetQueryString()
            {
                return this._queryString;
            }
    
            public override byte[] GetQueryStringRawBytes()
            {
                return this._queryStringBytes;
            }
    
            public override string GetRawUrl()
            {
                return this._url;
            }
    
            public override string GetRemoteAddress()
            {
                this._connectionPermission.Assert();
                return this._connection.RemoteIP;
            }
    
            public override int GetRemotePort()
            {
                return 0;
            }
    
            public override string GetServerName()
            {
                string localAddress = this.GetLocalAddress();
                if ((!localAddress.Equals("127.0.0.1") && !localAddress.Equals("::1")) && !localAddress.Equals("::ffff:127.0.0.1"))
                {
                    return localAddress;
                }
                return "localhost";
            }
    
            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 (this.GetUserToken() != IntPtr.Zero)
                            {
                                processUser = this._host.GetProcessUser();
                            }
                            return processUser;
                        }
                        if ((str2 == "AUTH_TYPE") && (this.GetUserToken() != IntPtr.Zero))
                        {
                            processUser = "NTLM";
                        }
                        return processUser;
                    }
                }
                else
                {
                    return this._allRawHeaders;
                }
                return this._prot;
            }
    
            public override string GetUnknownRequestHeader(string name)
            {
                int length = this._unknownRequestHeaders.Length;
                for (int i = 0; i < length; i++)
                {
                    if (string.Compare(name, this._unknownRequestHeaders[i][0], StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return this._unknownRequestHeaders[i][1];
                    }
                }
                return null;
            }
    
            public override string[][] GetUnknownRequestHeaders()
            {
                return this._unknownRequestHeaders;
            }
    
            public override string GetUriPath()
            {
                return this._path;
            }
    
            public override IntPtr GetUserToken()
            {
                return this._host.GetProcessToken();
            }
    
            public override bool HeadersSent()
            {
                return this._headersSent;
            }
    
            private bool IsBadPath()
            {
                return ((this._path.IndexOfAny(badPathChars) >= 0) || ((CultureInfo.InvariantCulture.CompareInfo.IndexOf(this._path, "..", CompareOptions.Ordinal) >= 0) || (CultureInfo.InvariantCulture.CompareInfo.IndexOf(this._path, "//", CompareOptions.Ordinal) >= 0)));
            }
    
            public override bool IsClientConnected()
            {
                this._connectionPermission.Assert();
                return this._connection.Connected;
            }
    
            public override bool IsEntireEntityBodyIsPreloaded()
            {
                return (this._contentLength == this._preloadedContentLength);
            }
    
            private bool IsRequestForRestrictedDirectory()
            {
                string str = CultureInfo.InvariantCulture.TextInfo.ToLower(this._path);
                if (this._host.VirtualPath != "/")
                {
                    str = str.Substring(this._host.VirtualPath.Length);
                }
                foreach (string str2 in restrictedDirs)
                {
                    if (str.StartsWith(str2, StringComparison.Ordinal) && ((str.Length == str2.Length) || (str[str2.Length] == '/')))
                    {
                        return true;
                    }
                }
                return false;
            }
    
            public override string MapPath(string path)
            {
                string physicalPath = string.Empty;
                bool isClientScriptPath = false;
                if (((path == null) || (path.Length == 0)) || path.Equals("/"))
                {
                    if (this._host.VirtualPath == "/")
                    {
                        physicalPath = this._host.PhysicalPath;
                    }
                    else
                    {
                        physicalPath = Environment.SystemDirectory;
                    }
                }
                else if (this._host.IsVirtualPathAppPath(path))
                {
                    physicalPath = this._host.PhysicalPath;
                }
                else if (this._host.IsVirtualPathInApp(path, out isClientScriptPath))
                {
                    if (isClientScriptPath)
                    {
                        physicalPath = this._host.PhysicalClientScriptPath + path.Substring(this._host.NormalizedClientScriptPath.Length);
                    }
                    else
                    {
                        physicalPath = this._host.PhysicalPath + path.Substring(this._host.NormalizedVirtualPath.Length);
                    }
                }
                else if (path.StartsWith("/", StringComparison.Ordinal))
                {
                    physicalPath = this._host.PhysicalPath + path.Substring(1);
                }
                else
                {
                    physicalPath = this._host.PhysicalPath + path;
                }
                physicalPath = physicalPath.Replace('/', '\\');
                if (physicalPath.EndsWith(@"\", StringComparison.Ordinal) && !physicalPath.EndsWith(@":\", StringComparison.Ordinal))
                {
                    physicalPath = physicalPath.Substring(0, physicalPath.Length - 1);
                }
                return physicalPath;
            }
    
            private void ParseHeaders()
            {
                this._knownRequestHeaders = new string[40];
                ArrayList list = new ArrayList();
                for (int i = 1; i < this._headerByteStrings.Count; i++)
                {
                    string str = ((ByteString) this._headerByteStrings[i]).GetString();
                    int index = str.IndexOf(':');
                    if (index >= 0)
                    {
                        string header = str.Substring(0, index).Trim();
                        string str3 = str.Substring(index + 1).Trim();
                        int knownRequestHeaderIndex = HttpWorkerRequest.GetKnownRequestHeaderIndex(header);
                        if (knownRequestHeaderIndex >= 0)
                        {
                            this._knownRequestHeaders[knownRequestHeaderIndex] = str3;
                        }
                        else
                        {
                            list.Add(header);
                            list.Add(str3);
                        }
                    }
                }
                int num4 = list.Count / 2;
                this._unknownRequestHeaders = new string[num4][];
                int num5 = 0;
                for (int j = 0; j < num4; j++)
                {
                    this._unknownRequestHeaders[j] = new string[] { (string) list[num5++], (string) list[num5++] };
                }
                if (this._headerByteStrings.Count > 1)
                {
                    this._allRawHeaders = Encoding.UTF8.GetString(this._headerBytes, this._startHeadersOffset, this._endHeadersOffset - this._startHeadersOffset);
                }
                else
                {
                    this._allRawHeaders = string.Empty;
                }
            }
    
            private void ParsePostedContent()
            {
                this._contentLength = 0;
                this._preloadedContentLength = 0;
                string s = this._knownRequestHeaders[11];
                if (s != null)
                {
                    try
                    {
                        this._contentLength = int.Parse(s, CultureInfo.InvariantCulture);
                    }
                    catch
                    {
                    }
                }
                if (this._headerBytes.Length > this._endHeadersOffset)
                {
                    this._preloadedContentLength = this._headerBytes.Length - this._endHeadersOffset;
                    if (this._preloadedContentLength > this._contentLength)
                    {
                        this._preloadedContentLength = this._contentLength;
                    }
                    if (this._preloadedContentLength > 0)
                    {
                        this._preloadedContent = new byte[this._preloadedContentLength];
                        Buffer.BlockCopy(this._headerBytes, this._endHeadersOffset, this._preloadedContent, 0, this._preloadedContentLength);
                    }
                }
            }
    
            private void ParseRequestLine()
            {
                ByteString[] strArray = ((ByteString) this._headerByteStrings[0]).Split(' ');
                if (((strArray == null) || (strArray.Length < 2)) || (strArray.Length > 3))
                {
                    this._connection.WriteErrorAndClose(400);
                }
                else
                {
                    this._verb = strArray[0].GetString();
                    ByteString str2 = strArray[1];
                    this._url = str2.GetString();
                    if (this._url.IndexOf((char)0xfffd) >= 0)
                    {
                        this._url = str2.GetString(Encoding.Default);
                    }
                    if (strArray.Length == 3)
                    {
                        this._prot = strArray[2].GetString();
                    }
                    else
                    {
                        this._prot = "HTTP/1.0";
                    }
                    int index = str2.IndexOf('?');
                    if (index > 0)
                    {
                        this._queryStringBytes = str2.Substring(index + 1).GetBytes();
                    }
                    else
                    {
                        this._queryStringBytes = new byte[0];
                    }
                    index = this._url.IndexOf('?');
                    if (index > 0)
                    {
                        this._path = this._url.Substring(0, index);
                        this._queryString = this._url.Substring(index + 1);
                    }
                    else
                    {
                        this._path = this._url;
                        this._queryString = string.Empty;
                    }
                    if (this._path.IndexOf('%') >= 0)
                    {
                        this._path = HttpUtility.UrlDecode(this._path, Encoding.UTF8);
                        index = this._url.IndexOf('?');
                        if (index >= 0)
                        {
                            this._url = this._path + this._url.Substring(index);
                        }
                        else
                        {
                            this._url = this._path;
                        }
                    }
                    int startIndex = this._path.LastIndexOf('.');
                    int num3 = this._path.LastIndexOf('/');
                    if (((startIndex >= 0) && (num3 >= 0)) && (startIndex < num3))
                    {
                        int length = this._path.IndexOf('/', startIndex);
                        this._filePath = this._path.Substring(0, length);
                        this._pathInfo = this._path.Substring(length);
                    }
                    else
                    {
                        this._filePath = this._path;
                        this._pathInfo = string.Empty;
                    }
                    this._pathTranslated = this.MapPath(this._filePath);
                }
            }
    
            private void PrepareResponse()
            {
                this._headersSent = false;
                this._responseStatus = 200;
                this._responseHeadersBuilder = new StringBuilder();
                this._responseBodyBytes = new ArrayList();
            }
    
            [AspNetHostingPermission(SecurityAction.Assert, Level=AspNetHostingPermissionLevel.Medium)]
            public void Process()
            {
                if (this.TryParseRequest())
                {
                    if (((this._verb == "POST") && (this._contentLength > 0)) && (this._preloadedContentLength < this._contentLength))
                    {
                        this._connection.Write100Continue();
                    }
                    if (!this._host.RequireAuthentication || this.TryNtlmAuthenticate())
                    {
                        if (this._isClientScriptPath)
                        {
                            this._connection.WriteEntireResponseFromFile(this._host.PhysicalClientScriptPath + this._path.Substring(this._host.NormalizedClientScriptPath.Length), false);
                        }
                        else if (this.IsRequestForRestrictedDirectory())
                        {
                            this._connection.WriteErrorAndClose(0x193);
                        }
                        else if (!this.ProcessDefaultDocumentRequest())
                        {
                            this.PrepareResponse();
                            HttpRuntime.ProcessRequest(this);
                        }
                    }
                }
            }
    
            private bool ProcessDefaultDocumentRequest()
            {
                if (this._verb == "GET")
                {
                    string path = this._pathTranslated;
                    if (this._pathInfo.Length > 0)
                    {
                        path = this.MapPath(this._path);
                    }
                    if (!Directory.Exists(path))
                    {
                        return false;
                    }
                    if (!this._path.EndsWith("/", StringComparison.Ordinal))
                    {
                        string str2 = this._path + "/";
                        string extraHeaders = "Location: " + UrlEncodeRedirect(str2) + "\r\n";
                        string body = "<html><head><title>Object moved</title></head><body>\r\n<h2>Object moved to <a href='" + str2 + "'>here</a>.</h2>\r\n</body></html>\r\n";
                        this._connection.WriteEntireResponseFromString(0x12e, extraHeaders, body, false);
                        return true;
                    }
                    foreach (string str5 in defaultFileNames)
                    {
                        string str6 = path + @"\" + str5;
                        if (File.Exists(str6))
                        {
                            this._path = this._path + str5;
                            this._filePath = this._path;
                            this._url = (this._queryString != null) ? (this._path + "?" + this._queryString) : this._path;
                            this._pathTranslated = str6;
                            return false;
                        }
                    }
                }
                return false;
            }
    
            private bool ProcessDirectoryListingRequest()
            {
                if (this._verb != "GET")
                {
                    return false;
                }
                string path = this._pathTranslated;
                if (this._pathInfo.Length > 0)
                {
                    path = this.MapPath(this._path);
                }
                if (!Directory.Exists(path))
                {
                    return false;
                }
                if (this._host.DisableDirectoryListing)
                {
                    return false;
                }
                FileSystemInfo[] elements = null;
                try
                {
                    elements = new DirectoryInfo(path).GetFileSystemInfos();
                }
                catch
                {
                }
                string str2 = null;
                if (this._path.Length > 1)
                {
                    int length = this._path.LastIndexOf('/', this._path.Length - 2);
                    str2 = (length > 0) ? this._path.Substring(0, length) : "/";
                    if (!this._host.IsVirtualPathInApp(str2))
                    {
                        str2 = null;
                    }
                }
                this._connection.WriteEntireResponseFromString(200, "Content-type: text/html; charset=utf-8\r\n", Messages.FormatDirectoryListing(this._path, str2, elements), false);
                return true;
            }
    
            private void ReadAllHeaders()
            {
                this._headerBytes = null;
                do
                {
                    if (!this.TryReadAllHeaders())
                    {
                        return;
                    }
                }
                while (this._endHeadersOffset < 0);
            }
    
            public override int ReadEntityBody(byte[] buffer, int size)
            {
                int count = 0;
                this._connectionPermission.Assert();
                byte[] src = this._connection.ReadRequestBytes(size);
                if ((src != null) && (src.Length > 0))
                {
                    count = src.Length;
                    Buffer.BlockCopy(src, 0, buffer, 0, count);
                }
                return count;
            }
    
            private void Reset()
            {
                this._headerBytes = null;
                this._startHeadersOffset = 0;
                this._endHeadersOffset = 0;
                this._headerByteStrings = null;
                this._isClientScriptPath = false;
                this._verb = null;
                this._url = null;
                this._prot = null;
                this._path = null;
                this._filePath = null;
                this._pathInfo = null;
                this._pathTranslated = null;
                this._queryString = null;
                this._queryStringBytes = null;
                this._contentLength = 0;
                this._preloadedContentLength = 0;
                this._preloadedContent = null;
                this._allRawHeaders = null;
                this._unknownRequestHeaders = null;
                this._knownRequestHeaders = null;
                this._specialCaseStaticFileHeaders = false;
            }
    
            public override void SendCalculatedContentLength(int contentLength)
            {
                if (!this._headersSent)
                {
                    this._responseHeadersBuilder.Append("Content-Length: ");
                    this._responseHeadersBuilder.Append(contentLength.ToString(CultureInfo.InvariantCulture));
                    this._responseHeadersBuilder.Append("\r\n");
                }
            }
    
            public override void SendKnownResponseHeader(int index, string value)
            {
                if (!this._headersSent)
                {
                    switch (index)
                    {
                        case 1:
                        case 2:
                        case 0x1a:
                            return;
    
                        case 0x12:
                        case 0x13:
                            if (!this._specialCaseStaticFileHeaders)
                            {
                                break;
                            }
                            return;
    
                        case 20:
                            if (!(value == "bytes"))
                            {
                                break;
                            }
                            this._specialCaseStaticFileHeaders = true;
                            return;
                    }
                    this._responseHeadersBuilder.Append(HttpWorkerRequest.GetKnownResponseHeaderName(index));
                    this._responseHeadersBuilder.Append(": ");
                    this._responseHeadersBuilder.Append(value);
                    this._responseHeadersBuilder.Append("\r\n");
                }
            }
    
            public override void SendResponseFromFile(IntPtr handle, long offset, long length)
            {
                if (length != 0)
                {
                    FileStream f = null;
                    try
                    {
                        SafeFileHandle handle2 = new SafeFileHandle(handle, false);
                        f = new FileStream(handle2, FileAccess.Read);
                        this.SendResponseFromFileStream(f, offset, length);
                    }
                    finally
                    {
                        if (f != null)
                        {
                            f.Close();
                            f = null;
                        }
                    }
                }
            }
    
            public override void SendResponseFromFile(string filename, long offset, long length)
            {
                if (length != 0)
                {
                    FileStream f = null;
                    try
                    {
                        f = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
                        this.SendResponseFromFileStream(f, offset, length);
                    }
                    finally
                    {
                        if (f != null)
                        {
                            f.Close();
                        }
                    }
                }
            }
    
            private void SendResponseFromFileStream(FileStream f, long offset, long length)
            {
                long num = f.Length;
                if (length == -1)
                {
                    length = num - offset;
                }
                if (((length != 0) && (offset >= 0)) && (length <= (num - offset)))
                {
                    if (offset > 0)
                    {
                        f.Seek(offset, SeekOrigin.Begin);
                    }
                    if (length <= 0x10000)
                    {
                        byte[] buffer = new byte[(int) length];
                        int num2 = f.Read(buffer, 0, (int) length);
                        this.SendResponseFromMemory(buffer, num2);
                    }
                    else
                    {
                        byte[] buffer2 = new byte[0x10000];
                        int num3 = (int) length;
                        while (num3 > 0)
                        {
                            int count = (num3 < 0x10000) ? num3 : 0x10000;
                            int num5 = f.Read(buffer2, 0, count);
                            this.SendResponseFromMemory(buffer2, num5);
                            num3 -= num5;
                            if ((num3 > 0) && (num5 > 0))
                            {
                                this.FlushResponse(false);
                            }
                        }
                    }
                }
            }
    
            public override void SendResponseFromMemory(byte[] data, int length)
            {
                if (length > 0)
                {
                    byte[] dst = new byte[length];
                    Buffer.BlockCopy(data, 0, dst, 0, length);
                    this._responseBodyBytes.Add(dst);
                }
            }
    
            public override void SendStatus(int statusCode, string statusDescription)
            {
                this._responseStatus = statusCode;
            }
    
            public override void SendUnknownResponseHeader(string name, string value)
            {
                if (!this._headersSent)
                {
                    this._responseHeadersBuilder.Append(name);
                    this._responseHeadersBuilder.Append(": ");
                    this._responseHeadersBuilder.Append(value);
                    this._responseHeadersBuilder.Append("\r\n");
                }
            }
    
            private void SkipAllPostedContent()
            {
                if ((this._contentLength > 0) && (this._preloadedContentLength < this._contentLength))
                {
                    byte[] buffer;
                    for (int i = this._contentLength - this._preloadedContentLength; i > 0; i -= buffer.Length)
                    {
                        buffer = this._connection.ReadRequestBytes(i);
                        if ((buffer == null) || (buffer.Length == 0))
                        {
                            return;
                        }
                    }
                }
            }
    
            [SecurityPermission(SecurityAction.Assert, UnmanagedCode=true), SecurityPermission(SecurityAction.Assert, ControlPrincipal=true)]
            private bool TryNtlmAuthenticate()
            {
                try
                {
                    using (NtlmAuth auth = new NtlmAuth())
                    {
                        do
                        {
                            string blobString = null;
                            string extraHeaders = this._knownRequestHeaders[0x18];
                            if ((extraHeaders != null) && extraHeaders.StartsWith("NTLM ", StringComparison.Ordinal))
                            {
                                blobString = extraHeaders.Substring(5);
                            }
                            if (blobString != null)
                            {
                                if (!auth.Authenticate(blobString))
                                {
                                    this._connection.WriteErrorAndClose(0x193);
                                    return false;
                                }
                                if (auth.Completed)
                                {
                                    goto Label_009A;
                                }
                                extraHeaders = "WWW-Authenticate: NTLM " + auth.Blob + "\r\n";
                            }
                            else
                            {
                                extraHeaders = "WWW-Authenticate: NTLM\r\n";
                            }
                            this.SkipAllPostedContent();
                            this._connection.WriteErrorWithExtraHeadersAndKeepAlive(0x191, extraHeaders);
                        }
                        while (this.TryParseRequest());
                        return false;
                    Label_009A:
                        if (this._host.GetProcessSID() != auth.SID)
                        {
                            this._connection.WriteErrorAndClose(0x193);
                            return false;
                        }
                    }
                }
                catch
                {
                    try
                    {
                        this._connection.WriteErrorAndClose(500);
                    }
                    catch
                    {
                    }
                    return false;
                }
                return true;
            }
    
            private bool TryParseRequest()
            {
                this.Reset();
                this.ReadAllHeaders();
                //if (!this._connection.IsLocal)
                //{
                //    this._connection.WriteErrorAndClose(0x193);
                //    return false;
                //}
                if (((this._headerBytes == null) || (this._endHeadersOffset < 0)) || ((this._headerByteStrings == null) || (this._headerByteStrings.Count == 0)))
                {
                    this._connection.WriteErrorAndClose(400);
                    return false;
                }
                this.ParseRequestLine();
                if (this.IsBadPath())
                {
                    this._connection.WriteErrorAndClose(400);
                    return false;
                }
                if (!this._host.IsVirtualPathInApp(this._path, out this._isClientScriptPath))
                {
                    this._connection.WriteErrorAndClose(0x194);
                    return false;
                }
                this.ParseHeaders();
                this.ParsePostedContent();
                return true;
            }
    
            private bool TryReadAllHeaders()
            {
                byte[] src = this._connection.ReadRequestBytes(0x8000);
                if ((src == null) || (src.Length == 0))
                {
                    return false;
                }
                if (this._headerBytes != null)
                {
                    int num = src.Length + this._headerBytes.Length;
                    if (num > 0x8000)
                    {
                        return false;
                    }
                    byte[] dst = new byte[num];
                    Buffer.BlockCopy(this._headerBytes, 0, dst, 0, this._headerBytes.Length);
                    Buffer.BlockCopy(src, 0, dst, this._headerBytes.Length, src.Length);
                    this._headerBytes = dst;
                }
                else
                {
                    this._headerBytes = src;
                }
                this._startHeadersOffset = -1;
                this._endHeadersOffset = -1;
                this._headerByteStrings = new ArrayList();
                ByteParser parser = new ByteParser(this._headerBytes);
                while (true)
                {
                    ByteString str = parser.ReadLine();
                    if (str == null)
                    {
                        break;
                    }
                    if (this._startHeadersOffset < 0)
                    {
                        this._startHeadersOffset = parser.CurrentOffset;
                    }
                    if (str.IsEmpty)
                    {
                        this._endHeadersOffset = parser.CurrentOffset;
                        break;
                    }
                    this._headerByteStrings.Add(str);
                }
                return true;
            }
    
            private static string UrlEncodeRedirect(string path)
            {
                byte[] bytes = Encoding.UTF8.GetBytes(path);
                int length = bytes.Length;
                int num2 = 0;
                for (int i = 0; i < length; i++)
                {
                    if ((bytes[i] & 0x80) != 0)
                    {
                        num2++;
                    }
                }
                if (num2 > 0)
                {
                    byte[] buffer2 = new byte[length + (num2 * 2)];
                    int num4 = 0;
                    for (int j = 0; j < length; j++)
                    {
                        byte num6 = bytes[j];
                        if ((num6 & 0x80) == 0)
                        {
                            buffer2[num4++] = num6;
                        }
                        else
                        {
                            buffer2[num4++] = 0x25;
                            buffer2[num4++] = (byte) IntToHex[(num6 >> 4) & 15];
                            buffer2[num4++] = (byte) IntToHex[num6 & 15];
                        }
                    }
                    path = Encoding.ASCII.GetString(buffer2);
                }
                if (path.IndexOf(' ') >= 0)
                {
                    path = path.Replace(" ", "%20");
                }
                return path;
            }
        }
    }
    Server.cs
    namespace Microsoft.VisualStudio.WebHost
    {
        using System;
        using System.Globalization;
        using System.Net;
        using System.Net.Sockets;
        using System.Runtime.InteropServices;
        using System.Security.Permissions;
        using System.Security.Principal;
        using System.Threading;
        using System.Web.Hosting;
        using System.Web;
        using System.Reflection;
    
        [PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust"), PermissionSet(SecurityAction.LinkDemand, Name = "Everything")]
        public class Server : MarshalByRefObject
        {
            private ApplicationManager _appManager;
            private bool _disableDirectoryListing;
            private Host _host;
            private object _lockObject;
            private WaitCallback _onSocketAccept;
            private WaitCallback _onStart;
            private string _physicalPath;
            private int _port;
            private IntPtr _processToken;
            private string _processUser;
            private bool _requireAuthentication;
            private bool _shutdownInProgress;
            private Socket _socketIpv4;
            private Socket _socketIpv6;
            private string _virtualPath;
            private const int SecurityImpersonation = 2;
            private const int TOKEN_ALL_ACCESS = 0xf01ff;
            private const int TOKEN_EXECUTE = 0x20000;
            private const int TOKEN_IMPERSONATE = 4;
            private const int TOKEN_READ = 0x20008;
    
            public Server(int port, string virtualPath, string physicalPath)
                : this(port, virtualPath, physicalPath, false, false)
            {
            }
    
            public Server(int port, string virtualPath, string physicalPath, bool requireAuthentication)
                : this(port, virtualPath, physicalPath, requireAuthentication, false)
            {
            }
    
            public Server(int port, string virtualPath, string physicalPath, bool requireAuthentication, bool disableDirectoryListing)
            {
                this._lockObject = new object();
                this._port = port;
                this._virtualPath = virtualPath;
                this._physicalPath = physicalPath.EndsWith(@"\", StringComparison.Ordinal) ? physicalPath : (physicalPath + @"\");
                this._requireAuthentication = requireAuthentication;
                this._disableDirectoryListing = disableDirectoryListing;
                this._onSocketAccept = new WaitCallback(this.OnSocketAccept);
                this._onStart = new WaitCallback(this.OnStart);
                this._appManager = ApplicationManager.GetApplicationManager();
                this.ObtainProcessToken();
            }
    
            private Socket CreateSocketBindAndListen(AddressFamily family, IPAddress ipAddress, int port)
            {
                Socket socket = new Socket(family, SocketType.Stream, ProtocolType.Tcp)
                {
                    ExclusiveAddressUse = false
                };
                try
                {
                    socket.Bind(new IPEndPoint(ipAddress, port));
                }
                catch
                {
                    socket.Close();
                    socket = null;
                    throw;
                }
                socket.Listen(0x7fffffff);
                return socket;
            }
    
            [DllImport("KERNEL32.DLL", SetLastError = true)]
            private static extern IntPtr GetCurrentThread();
            private Host GetHost()
            {
                if (this._shutdownInProgress)
                {
                    return null;
                }
                Host host = this._host;
                if (host == null)
                {
                    lock (this._lockObject)
                    {
                        host = this._host;
                        if (host == null)
                        {
                            string appId = (this._virtualPath + this._physicalPath).ToLowerInvariant().GetHashCode().ToString("x", CultureInfo.InvariantCulture);
                            //this._host = (Host) this._appManager.CreateObject(appId, typeof(Host), this._virtualPath, this._physicalPath, false);
                            Type hostType = typeof(Host);
                            var buildManagerHostType = typeof(HttpRuntime).Assembly.GetType("System.Web.Compilation.BuildManagerHost");
                            var buildManagerHost = _appManager.CreateObject(appId, buildManagerHostType, _virtualPath, _physicalPath, false);
                            buildManagerHostType.InvokeMember("RegisterAssembly", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic, null, buildManagerHost, new object[] { hostType.Assembly.FullName, hostType.Assembly.Location });
                           
                            this._host = (Host) this._appManager.CreateObject(appId, hostType, this._virtualPath, this._physicalPath, false);
                            this._host.Configure(this, this._port, this._virtualPath, this._physicalPath, this._requireAuthentication, this._disableDirectoryListing);
                            host = this._host;
                        }
                    }
                }
                return host;
            }
          
            public IntPtr GetProcessToken()
            {
                return this._processToken;
            }
    
            public string GetProcessUser()
            {
                return this._processUser;
            }
    
            internal void HostStopped()
            {
                this._host = null;
            }
    
            [DllImport("ADVAPI32.DLL", SetLastError = true)]
            private static extern bool ImpersonateSelf(int level);
            public override object InitializeLifetimeService()
            {
                return null;
            }
    
            private void ObtainProcessToken()
            {
                if (ImpersonateSelf(2))
                {
                    OpenThreadToken(GetCurrentThread(), 0xf01ff, true, ref this._processToken);
                    RevertToSelf();
                    this._processUser = WindowsIdentity.GetCurrent().Name;
                }
            }
    
            private void OnSocketAccept(object acceptedSocket)
            {
                if (!this._shutdownInProgress)
                {
                    Microsoft.VisualStudio.WebHost.Connection conn = new Microsoft.VisualStudio.WebHost.Connection(this, (Socket)acceptedSocket);
                    if (conn.WaitForRequestBytes() == 0)
                    {
                        conn.WriteErrorAndClose(400);
                    }
                    else
                    {
                        Host host = this.GetHost();
                        if (host == null)
                        {
                            conn.WriteErrorAndClose(500);
                        }
                        else
                        {
                            host.ProcessRequest(conn);
                        }
                    }
                }
            }
    
            private void OnStart(object listeningSocket)
            {
                while (!this._shutdownInProgress)
                {
                    try
                    {
                        if (listeningSocket != null)
                        {
                            Socket state = ((Socket)listeningSocket).Accept();
                            ThreadPool.QueueUserWorkItem(this._onSocketAccept, state);
                        }
                        continue;
                    }
                    catch
                    {
                        Thread.Sleep(100);
                        continue;
                    }
                }
            }
    
            [DllImport("ADVAPI32.DLL", SetLastError = true)]
            private static extern int OpenThreadToken(IntPtr thread, int access, bool openAsSelf, ref IntPtr hToken);
            [DllImport("ADVAPI32.DLL", SetLastError = true)]
            private static extern int RevertToSelf();
            public void Start()
            {
                bool flag = false;
                flag = Socket.OSSupportsIPv4;
                if (Socket.OSSupportsIPv6)
                {
                    try
                    {
                        this._socketIpv6 = this.CreateSocketBindAndListen(AddressFamily.InterNetworkV6, IPAddress.IPv6Loopback, this._port);
                    }
                    catch (SocketException exception)
                    {
                        if ((exception.SocketErrorCode == SocketError.AddressAlreadyInUse) || !flag)
                        {
                            throw;
                        }
                    }
                }
                if (flag)
                {
                    try
                    {
                      // Environment.MachineName
                        IPHostEntry hosts = Dns.GetHostByName(Environment.MachineName);
                        IPAddress address = IPAddress.Loopback;
                        if (hosts.AddressList.Length > 0)
                            address = hosts.AddressList[0];
                        this._socketIpv4 = this.CreateSocketBindAndListen(AddressFamily.InterNetwork, address, this._port);
                    }
                    catch (SocketException)
                    {
                        if (this._socketIpv6 == null)
                        {
                            throw;
                        }
                    }
                }
                if (this._socketIpv6 != null)
                {
                    ThreadPool.QueueUserWorkItem(this._onStart, this._socketIpv6);
                }
                if (this._socketIpv4 != null)
                {
                    ThreadPool.QueueUserWorkItem(this._onStart, this._socketIpv4);
                }
            }
    
            public void Stop()
            {
                this._shutdownInProgress = true;
                try
                {
                    if (this._socketIpv4 != null)
                    {
                        this._socketIpv4.Close();
                    }
                    if (this._socketIpv6 != null)
                    {
                        this._socketIpv6.Close();
                    }
                }
                catch
                {
                }
                finally
                {
                    this._socketIpv4 = null;
                    this._socketIpv6 = null;
                }
                try
                {
                    if (this._host != null)
                    {
                        this._host.Shutdown();
                    }
                    while (this._host != null)
                    {
                        Thread.Sleep(100);
                    }
                }
                catch
                {
                }
                finally
                {
                    this._host = null;
                }
            }
    
            public string PhysicalPath
            {
                get
                {
                    return this._physicalPath;
                }
            }
    
            public int Port
            {
                get
                {
                    return this._port;
                }
            }
    
            public string RootUrl
            {
                get
                {
                    if (this._port != 80)
                    {
                        return ("http://localhost:" + this._port + this._virtualPath);
                    }
                    return ("http://localhost" + this._virtualPath);
                }
            }
    
            public string VirtualPath
            {
                get
                {
                    return this._virtualPath;
                }
            }
        }
    }

    调用代码:

         Server s = new Server(49152, "/", @"C:\Users\majiang\Documents\Visual Studio 2010\Projects\ConsoleApp\WebApp");
                s.Start();

    欢迎大家拍砖

  • 相关阅读:
    struts2简介
    项目整合SpringDataRedis
    SpringDataRedis入门Demo
    包管理-rpm
    文件查找与压缩
    N042第一周
    Shell
    Linux下终端字体颜色设置方法
    文本处理工具作业
    正则表达式
  • 原文地址:https://www.cnblogs.com/majiang/p/2674535.html
Copyright © 2011-2022 走看看