123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623 |
- #region
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Globalization;
- using System.IO;
- using System.Net;
- using System.Net.Sockets;
- using System.Reflection;
- using System.Runtime.Remoting;
- using System.Security.Permissions;
- using System.Security.Principal;
- using System.Text;
- using System.Threading;
- using System.Web;
- using System.Web.Hosting;
- using CassiniDev.Configuration;
- using CassiniDev.ServerLog;
- #endregion
- namespace CassiniDev
- {
- [PermissionSet(SecurityAction.LinkDemand, Name = "Everything"),
- PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
- public class Server : MarshalByRefObject, IDisposable
- {
- private bool _useLogger;
- public List<string> Plugins = new List<string>();
- private readonly ApplicationManager _appManager;
- private readonly bool _disableDirectoryListing;
- private readonly string _hostName;
- private readonly IPAddress _ipAddress;
- private readonly object _lockObject;
- private readonly string _physicalPath;
- private readonly int _port;
- private readonly bool _requireAuthentication;
- private readonly int _timeoutInterval;
- private readonly string _virtualPath;
- private bool _disposed;
- private Host _host;
- private IntPtr _processToken;
- private string _processUser;
- private int _requestCount;
- private bool _shutdownInProgress;
- private Socket _socket;
- private Timer _timer;
- public Server(int port, string virtualPath, string physicalPath)
- : this(port, virtualPath, physicalPath, false, false)
- {
- }
- public Server(int port, string physicalPath)
- : this(port, "/", physicalPath, IPAddress.Loopback)
- {
- }
- public Server(string physicalPath)
- : this(CassiniNetworkUtils.GetAvailablePort(32768, 65535, IPAddress.Loopback, false), physicalPath)
- {
- }
- public Server(int port, string virtualPath, string physicalPath, IPAddress ipAddress, string hostName,
- int timeout, bool requireAuthentication)
- : this(port, virtualPath, physicalPath, ipAddress, hostName, timeout, requireAuthentication, 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, IPAddress ipAddress, string hostName)
- : this(port, virtualPath, physicalPath, ipAddress, hostName, 0, false, false)
- {
- }
- public Server(int port, string virtualPath, string physicalPath, IPAddress ipAddress, string hostName,
- int timeout, bool requireAuthentication, bool disableDirectoryListing)
- : this(port, virtualPath, physicalPath, requireAuthentication, disableDirectoryListing)
- {
- _ipAddress = ipAddress;
- _hostName = hostName;
- _timeoutInterval = timeout;
- }
- public Server(int port, string virtualPath, string physicalPath, IPAddress ipAddress)
- : this(port, virtualPath, physicalPath, ipAddress, null, 0, false, false)
- {
- }
- public Server(int port, string virtualPath, string physicalPath, bool requireAuthentication,
- bool disableDirectoryListing)
- {
- try
- {
-
-
- }
-
- catch
-
- {
- }
- _ipAddress = IPAddress.Any;
- _requireAuthentication = requireAuthentication;
- _disableDirectoryListing = disableDirectoryListing;
- _lockObject = new object();
- _port = port;
- _virtualPath = virtualPath;
- _physicalPath = Path.GetFullPath(physicalPath);
- _physicalPath = _physicalPath.EndsWith("\\", StringComparison.Ordinal)
- ? _physicalPath
- : _physicalPath + "\\";
- ProcessConfiguration();
- _appManager = ApplicationManager.GetApplicationManager();
- ObtainProcessToken();
- }
- private void ProcessConfiguration()
- {
- var config = CassiniDevConfigurationSection.Instance;
- if (config != null)
- {
- foreach (CassiniDevProfileElement profile in config.Profiles)
- {
- if (profile.Port == "*" || Convert.ToInt64(profile.Port) == _port)
- {
- foreach (PluginElement plugin in profile.Plugins)
- {
- Plugins.Insert(0, plugin.Type);
- }
- }
- }
- }
- }
- public Server(string physicalPath, bool requireAuthentication)
- : this(
- CassiniNetworkUtils.GetAvailablePort(32768, 65535, IPAddress.Loopback, false), "/", physicalPath,
- requireAuthentication)
- {
- }
- public Server(int port, string virtualPath, string physicalPath, IPAddress ipAddress, string hostName,
- int timeout)
- : this(port, virtualPath, physicalPath, ipAddress, hostName, timeout, false, false)
- {
- }
- public bool DisableDirectoryListing
- {
- get { return _disableDirectoryListing; }
- }
- public bool RequireAuthentication
- {
- get { return _requireAuthentication; }
- }
- public int TimeoutInterval
- {
- get { return _timeoutInterval; }
- }
- public string HostName
- {
- get { return _hostName; }
- }
- public IPAddress IPAddress
- {
- get { return _ipAddress; }
- }
- public string PhysicalPath
- {
- get { return _physicalPath; }
- }
- public int Port
- {
- get { return _port; }
- }
- public string RootUrl
- {
- get
- {
- string hostname = _hostName;
- if (string.IsNullOrEmpty(_hostName))
- {
- if (_ipAddress.Equals(IPAddress.Loopback) || _ipAddress.Equals(IPAddress.IPv6Loopback) ||
- _ipAddress.Equals(IPAddress.Any) || _ipAddress.Equals(IPAddress.IPv6Any))
- {
- hostname = "localhost";
- }
- else
- {
- hostname = _ipAddress.ToString();
- }
- }
- return _port != 80
- ?
- String.Format("http://{0}:{1}{2}", hostname, _port, _virtualPath)
- :
-
- string.Format("http://{0}{1}", hostname, _virtualPath);
- }
- }
- public string VirtualPath
- {
- get { return _virtualPath; }
- }
- #region IDisposable Members
- public void Dispose()
- {
- if (!_disposed)
- {
- ShutDown();
- }
- _disposed = true;
- GC.SuppressFinalize(this);
- }
- #endregion
- public event EventHandler<RequestEventArgs> RequestComplete;
- public event EventHandler TimedOut;
- public IntPtr GetProcessToken()
- {
- return _processToken;
- }
- public string GetProcessUser()
- {
- return _processUser;
- }
- public void HostStopped()
- {
- _host = null;
- }
- [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
- public override object InitializeLifetimeService()
- {
-
- return null;
- }
-
-
-
-
-
-
- public void OnRequestEnd(Connection conn)
- {
- try
- {
- OnRequestComplete(conn.Id, conn.RequestLog.Clone(), conn.ResponseLog.Clone());
- }
- catch
- {
-
- }
- RemotingServices.Disconnect(conn);
- DecrementRequestCount();
- }
- public void Start()
- {
- _socket = CreateSocketBindAndListen(AddressFamily.InterNetwork, _ipAddress, _port);
-
- DecrementRequestCount();
- ThreadPool.QueueUserWorkItem(delegate
- {
- while (!_shutdownInProgress)
- {
- try
- {
- Socket acceptedSocket = _socket.Accept();
- ThreadPool.QueueUserWorkItem(delegate
- {
- if (!_shutdownInProgress)
- {
- Connection conn = new Connection(this, acceptedSocket);
- if (conn.WaitForRequestBytes() == 0)
- {
- conn.WriteErrorAndClose(400);
- return;
- }
- Host host = GetHost();
- if (host == null)
- {
- conn.WriteErrorAndClose(500);
- return;
- }
- IncrementRequestCount();
- host.ProcessRequest(conn);
- }
- });
- }
- catch
- {
- Thread.Sleep(100);
- }
- }
- });
- }
- ~Server()
- {
- Dispose();
- }
- private static Socket CreateSocketBindAndListen(AddressFamily family, IPAddress address, int port)
- {
- Socket socket = new Socket(family, SocketType.Stream, ProtocolType.Tcp);
- socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
- socket.Bind(new IPEndPoint(address, port));
- socket.Listen((int)SocketOptionName.MaxConnections);
- return socket;
- }
-
-
-
-
-
-
-
-
-
-
-
- private object CreateWorkerAppDomainWithHost(string virtualPath, string physicalPath, Type hostType)
- {
-
-
- string uniqueAppString = string.Concat(virtualPath, physicalPath).ToLowerInvariant();
- string appId = (uniqueAppString.GetHashCode()).ToString("x", CultureInfo.InvariantCulture);
-
-
- Type buildManagerHostType = typeof(HttpRuntime).Assembly.GetType("System.Web.Compilation.BuildManagerHost");
- IRegisteredObject 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 });
-
-
-
- return _appManager.CreateObject(appId, hostType, virtualPath, physicalPath, false);
- }
- private void DecrementRequestCount()
- {
- lock (_lockObject)
- {
- _requestCount--;
- if (_requestCount < 1)
- {
- _requestCount = 0;
- if (_timeoutInterval > 0 && _timer == null)
- {
- _timer = new Timer(TimeOut, null, _timeoutInterval, Timeout.Infinite);
- }
- }
- }
- }
- private Host GetHost()
- {
- if (_shutdownInProgress)
- return null;
- Host host = _host;
- if (host == null)
- {
- #if NET40
- object obj2 = new object();
- bool flag = false;
- try
- {
- Monitor.Enter(obj2 = _lockObject, ref flag);
- host = _host;
- if (host == null)
- {
- host = (Host)CreateWorkerAppDomainWithHost(_virtualPath, _physicalPath, typeof(Host));
- host.Configure(this, _port, _virtualPath, _physicalPath, _requireAuthentication, _disableDirectoryListing);
- _host = host;
- }
- }
- finally
- {
- if (flag)
- {
- Monitor.Exit(obj2);
- }
- }
- #else
- lock (_lockObject)
- {
- host = _host;
- if (host == null)
- {
- host = (Host)CreateWorkerAppDomainWithHost(_virtualPath, _physicalPath, typeof(Host));
- host.Configure(this, _port, _virtualPath, _physicalPath, _requireAuthentication, _disableDirectoryListing);
- _host = host;
- }
- }
- #endif
- }
- return host;
- }
- private void IncrementRequestCount()
- {
- lock (_lockObject)
- {
- _requestCount++;
- if (_timer != null)
- {
- _timer.Dispose();
- _timer = null;
- }
- }
- }
- private void ObtainProcessToken()
- {
- if (Interop.ImpersonateSelf(2))
- {
- Interop.OpenThreadToken(Interop.GetCurrentThread(), 0xf01ff, true, ref _processToken);
- Interop.RevertToSelf();
-
- _processUser = WindowsIdentity.GetCurrent().Name;
-
- }
- }
- private void OnRequestComplete(Guid id, LogInfo requestLog, LogInfo responseLog)
- {
- PublishLogToCommonLogging(requestLog);
- PublishLogToCommonLogging(responseLog);
- EventHandler<RequestEventArgs> complete = RequestComplete;
- if (complete != null)
- {
- complete(this, new RequestEventArgs(id, requestLog, responseLog));
- }
- }
- private void PublishLogToCommonLogging(LogInfo item)
- {
- if(!_useLogger )
- {
- return;
- }
-
-
- {
-
- }
-
- }
- public void ShutDown()
- {
- if (_shutdownInProgress)
- {
- return;
- }
- _shutdownInProgress = true;
- try
- {
- if (_socket != null)
- {
- _socket.Close();
- }
- }
-
- catch
-
- {
-
- }
- finally
- {
- _socket = null;
- }
- try
- {
- if (_host != null)
- {
- _host.Shutdown();
- }
-
-
- while (_host != null)
- {
- new AutoResetEvent(false).WaitOne(100);
- }
- }
-
- catch
-
- {
-
- }
-
- }
- private void TimeOut(object ignored)
- {
- TimeOut();
- }
- public void TimeOut()
- {
- ShutDown();
- OnTimeOut();
- }
- private void OnTimeOut()
- {
- EventHandler handler = TimedOut;
- if (handler != null) handler(this, EventArgs.Empty);
- }
- }
- }
|