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

Server sv = new Server(, "/", @"D:\web", IPAddress.Any, null, "Login.aspx");
//  **********************************************************************************
// CassiniDev - http://cassinidev.codeplex.com
//
// Copyright (c) 2010 Sky Sanders. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is subject to terms and conditions of the Microsoft Public
// License (Ms-PL). A copy of the license can be found in the license.txt file
// included in this distribution.
//
// You must not remove this notice, or any other, from this software.
//
// ********************************************************************************** #region using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.Remoting;
using System.Security.Permissions;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Hosting; #endregion namespace SimpleWebServer
{
///<summary>
///</summary>
[PermissionSet(SecurityAction.LinkDemand, Name = "Everything"),
PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
public class Server : MarshalByRefObject, IDisposable
{
///<summary>
///</summary>
public List<string> Plugins = new List<string>();
///<summary>
///</summary>
public readonly ApplicationManager ApplicationManager; private readonly bool _disableDirectoryListing; private readonly string _hostName; private readonly IPAddress _ipAddress; private readonly object _lockObject; private readonly string _physicalPath; private readonly int _port;
private readonly bool _requireAuthentication;
//private readonly int _timeoutInterval;
private readonly string _virtualPath;
private bool _disposed; private Host _host; private IntPtr _processToken; private string _processUser; //private int _requestCount; private bool _shutdownInProgress; private Socket _socket; //private Timer _timer; private string _appId; private string _dfPage;
///<summary>
///</summary>
public string AppId
{
get { return _appId; }
}
///<summary>
///</summary>
public AppDomain HostAppDomain
{
get
{
if (_host == null)
{
GetHost();
}
if (_host != null)
{
return _host.AppDomain;
}
return null;
}
} ///<summary>
///</summary>
///<param name="port"></param>
///<param name="virtualPath"></param>
///<param name="physicalPath"></param>
public Server(int port, string virtualPath, string physicalPath)
: this(port, virtualPath, physicalPath, false, false)
{
} ///<summary>
///</summary>
///<param name="port"></param>
///<param name="physicalPath"></param>
public Server(int port, string physicalPath)
: this(port, "/", physicalPath, IPAddress.Loopback)
{
} ///<summary>
///</summary>
///<param name="port"></param>
///<param name="virtualPath"></param>
///<param name="physicalPath"></param>
///<param name="ipAddress"></param>
///<param name="hostName"></param>
///<param name="requireAuthentication"></param>
public Server(int port, string virtualPath, string physicalPath, IPAddress ipAddress, string hostName)
: this(port, virtualPath, physicalPath, ipAddress, hostName,false, false, null)
{
} ///<summary>
///</summary>
///<param name="port"></param>
///<param name="virtualPath"></param>
///<param name="physicalPath"></param>
///<param name="requireAuthentication"></param>
public Server(int port, string virtualPath, string physicalPath, bool requireAuthentication)
: this(port, virtualPath, physicalPath, requireAuthentication, false)
{
} ///<summary>
///</summary>
///<param name="port"></param>
///<param name="virtualPath"></param>
///<param name="physicalPath"></param>
///<param name="ipAddress"></param>
///<param name="hostName"></param>
public Server(int port, string virtualPath, string physicalPath, IPAddress ipAddress, string hostName,string dfPage)
: this(port, virtualPath, physicalPath, ipAddress, hostName, false, false, dfPage)
{
} ///<summary>
///</summary>
///<param name="port"></param>
///<param name="virtualPath"></param>
///<param name="physicalPath"></param>
///<param name="ipAddress"></param>
///<param name="hostName"></param>
///<param name="requireAuthentication"></param>
///<param name="disableDirectoryListing"></param>
public Server(int port, string virtualPath, string physicalPath, IPAddress ipAddress, string hostName,
bool requireAuthentication, bool disableDirectoryListing, string dfPage)
: this(port, virtualPath, physicalPath, requireAuthentication, disableDirectoryListing)
{
_ipAddress = ipAddress;
_hostName = hostName;
if (!String.IsNullOrEmpty(dfPage))
dfPage.TrimStart('/');
_dfPage = "/" + dfPage;
//_timeoutInterval = timeout;
} ///<summary>
///</summary>
///<param name="port"></param>
///<param name="virtualPath"></param>
///<param name="physicalPath"></param>
///<param name="ipAddress"></param>
public Server(int port, string virtualPath, string physicalPath, IPAddress ipAddress)
: this(port, virtualPath, physicalPath, ipAddress, null, false, false , null)
{
} ///<summary>
///</summary>
///<param name="port"></param>
///<param name="virtualPath"></param>
///<param name="physicalPath"></param>
///<param name="requireAuthentication"></param>
///<param name="disableDirectoryListing"></param>
public Server(int port, string virtualPath, string physicalPath, bool requireAuthentication,
bool disableDirectoryListing)
{
try
{
Assembly.ReflectionOnlyLoad("Common.Logging");
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{
}
_ipAddress = IPAddress.Loopback;
_requireAuthentication = requireAuthentication;
_disableDirectoryListing = disableDirectoryListing;
_lockObject = new object();
_port = port;
_virtualPath = virtualPath;
_physicalPath = Path.GetFullPath(physicalPath);
_physicalPath = _physicalPath.EndsWith("\\", StringComparison.Ordinal)
? _physicalPath
: _physicalPath + "\\"; ApplicationManager = ApplicationManager.GetApplicationManager();
string uniqueAppString = string.Concat(virtualPath, physicalPath,":",_port.ToString()).ToLowerInvariant();
_appId = (uniqueAppString.GetHashCode()).ToString("x", CultureInfo.InvariantCulture);
ObtainProcessToken();
} ///<summary>
///</summary>
public bool DisableDirectoryListing
{
get { return _disableDirectoryListing; }
} ///<summary>
///</summary>
public bool RequireAuthentication
{
get { return _requireAuthentication; }
} /////<summary>
/////</summary>
//public int TimeoutInterval
//{
// get { return _timeoutInterval; }
//} ///<summary>
///</summary>
public string HostName
{
get { return _hostName; }
} ///<summary>
///</summary>
// ReSharper disable InconsistentNaming
public IPAddress IPAddress
// ReSharper restore InconsistentNaming
{
get { return _ipAddress; }
} ///<summary>
///</summary>
public string PhysicalPath
{
get { return _physicalPath; }
} ///<summary>
///</summary>
public int Port
{
get { return _port; }
} ///<summary>
///</summary>
public string RootUrl
{
get
{
string hostname = _hostName;
if (string.IsNullOrEmpty(_hostName))
{
if (_ipAddress.Equals(IPAddress.Loopback) || _ipAddress.Equals(IPAddress.IPv6Loopback) ||
_ipAddress.Equals(IPAddress.Any) || _ipAddress.Equals(IPAddress.IPv6Any))
{
hostname = "localhost";
}
else
{
hostname = _ipAddress.ToString();
}
} return _port !=
?
String.Format("http://{0}:{1}{2}", hostname, _port, _virtualPath)
:
//FIX: #12017 - TODO:TEST
string.Format("http://{0}{1}", hostname, _virtualPath);
}
} ///<summary>
///</summary>
public string VirtualPath
{
get { return _virtualPath; }
} #region IDisposable Members /// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
/// <filterpriority></filterpriority>
public void Dispose()
{
if (!_disposed)
{
ShutDown();
}
_disposed = true;
GC.SuppressFinalize(this);
} #endregion ///<summary>
///</summary>
public event EventHandler<RequestEventArgs> RequestComplete; /////<summary>
/////</summary>
//public event EventHandler TimedOut; ///<summary>
///</summary>
///<returns></returns>
public IntPtr GetProcessToken()
{
return _processToken;
} ///<summary>
///</summary>
///<returns></returns>
public string GetProcessUser()
{
return _processUser;
} ///<summary>
///</summary>
public void HostStopped()
{
_host = null;
} /// <summary>
/// Obtains a lifetime service object to control the lifetime policy for this instance.
/// </summary>
/// <returns>
/// An object of type <see cref="T:System.Runtime.Remoting.Lifetime.ILease"/> used to control the lifetime policy for this instance. This is the current lifetime service object for this instance if one exists; otherwise, a new lifetime service object initialized to the value of the <see cref="P:System.Runtime.Remoting.Lifetime.LifetimeServices.LeaseManagerPollTime"/> property.
/// </returns>
/// <exception cref="T:System.Security.SecurityException">The immediate caller does not have infrastructure permission.
/// </exception><filterpriority></filterpriority><PermissionSet><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="RemotingConfiguration, Infrastructure"/></PermissionSet>
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
public override object InitializeLifetimeService()
{
// never expire the license
return null;
} // called at the end of request processing
// to disconnect the remoting proxy for Connection object
// and allow GC to pick it up
/// <summary>
/// </summary>
/// <param name="conn"></param>
/// <param name="userName"></param>
public void OnRequestEnd(Connection conn)
{
try
{
OnRequestComplete(conn.Id);
}
catch
{
// swallow - we don't want consumer killing the server
}
RemotingServices.Disconnect(conn);
//DecrementRequestCount();
} ///<summary>
///</summary>
public void Start()
{
_socket = CreateSocketBindAndListen(AddressFamily.InterNetwork, _ipAddress, _port); //start the timer
//DecrementRequestCount(); ThreadPool.QueueUserWorkItem(delegate
{
while (!_shutdownInProgress)
{
try
{
Socket acceptedSocket = _socket.Accept(); ThreadPool.QueueUserWorkItem(delegate
{
if (!_shutdownInProgress)
{
Connection conn = new Connection(this, acceptedSocket); if (conn.WaitForRequestBytes() == )
{
conn.WriteErrorAndClose();
return;
} Host host = GetHost(); if (host == null)
{
conn.WriteErrorAndClose();
return;
} //IncrementRequestCount();
host.ProcessRequest(conn,_dfPage);
}
});
}
catch
{
Thread.Sleep();
}
}
});
} /// <summary>
/// Allows an <see cref="T:System.Object"/> to attempt to free resources and perform other cleanup operations before the <see cref="T:System.Object"/> is reclaimed by garbage collection.
/// </summary>
~Server()
{
Dispose();
} private static Socket CreateSocketBindAndListen(AddressFamily family, IPAddress address, int port)
{
Socket socket = new Socket(family, SocketType.Stream, ProtocolType.Tcp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
socket.Bind(new IPEndPoint(address, port));
socket.Listen((int)SocketOptionName.MaxConnections);
return socket;
} /// <summary>
///
/// </summary>
/// <param name="virtualPath"></param>
/// <param name="physicalPath"></param>
/// <param name="hostType"></param>
/// <param name="port"></param>
/// <returns></returns>
/// <remarks>
/// This is Dmitry's hack to enable running outside of GAC.
/// There are some errors being thrown when running in proc
/// </remarks>
private object CreateWorkerAppDomainWithHost(string virtualPath, string physicalPath, Type hostType,int port)
{ // create BuildManagerHost in the worker app domain
//ApplicationManager appManager = ApplicationManager.GetApplicationManager();
Type buildManagerHostType = typeof(HttpRuntime).Assembly.GetType("System.Web.Compilation.BuildManagerHost");
IRegisteredObject buildManagerHost = ApplicationManager.CreateObject(_appId, buildManagerHostType, virtualPath,
physicalPath, false); // call BuildManagerHost.RegisterAssembly to make Host type loadable in the worker app domain
buildManagerHostType.InvokeMember("RegisterAssembly",
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic,
null,
buildManagerHost,
new object[] { hostType.Assembly.FullName, hostType.Assembly.Location }); // create Host in the worker app domain
// FIXME: getting FileLoadException Could not load file or assembly 'WebDev.WebServer20, Version=4.0.1.6, Culture=neutral, PublicKeyToken=f7f6e0b4240c7c27' or one of its dependencies. Failed to grant permission to execute. (Exception from HRESULT: 0x80131418)
// when running dnoa 3.4 samples - webdev is registering trust somewhere that we are not
return ApplicationManager.CreateObject(_appId, hostType, virtualPath, physicalPath, false);
} //private void DecrementRequestCount()
//{
// lock (_lockObject)
// {
// _requestCount--; // if (_requestCount < 1)
// {
// _requestCount = 0; // if (_timeoutInterval > 0 && _timer == null)
// {
// _timer = new Timer(TimeOut, null, _timeoutInterval, Timeout.Infinite);
// }
// }
// }
//} private Host GetHost()
{
if (_shutdownInProgress)
return null;
Host host = _host;
if (host == null)
{
#if NET40
object obj2 = new object();
bool flag = false;
try
{
Monitor.Enter(obj2 = _lockObject, ref flag);
host = _host;
if (host == null)
{
host = (Host)CreateWorkerAppDomainWithHost(_virtualPath, _physicalPath, typeof(Host),Port);
host.Configure(this, _port, _virtualPath, _physicalPath, _requireAuthentication, _disableDirectoryListing);
_host = host;
}
}
finally
{
if (flag)
{
Monitor.Exit(obj2);
}
}
#else lock (_lockObject)
{
host = _host;
if (host == null)
{
host = (Host)CreateWorkerAppDomainWithHost(_virtualPath, _physicalPath, typeof(Host),Port);
host.Configure(this, _port, _virtualPath, _physicalPath, _requireAuthentication, _disableDirectoryListing);
_host = host;
}
} #endif
} return host;
} //private void IncrementRequestCount()
//{ // lock (_lockObject)
// {
// _requestCount++; // if (_timer != null)
// { // _timer.Dispose();
// _timer = null;
// }
// }
//} private void ObtainProcessToken()
{
if (Interop.ImpersonateSelf())
{
Interop.OpenThreadToken(Interop.GetCurrentThread(), 0xf01ff, true, ref _processToken);
Interop.RevertToSelf();
// ReSharper disable PossibleNullReferenceException
_processUser = WindowsIdentity.GetCurrent().Name;
// ReSharper restore PossibleNullReferenceException
}
} private void OnRequestComplete(Guid id)
{ EventHandler<RequestEventArgs> complete = RequestComplete; if (complete != null)
{
complete(this, new RequestEventArgs(id));
}
} ///<summary>
///</summary>
public void ShutDown()
{
if (_shutdownInProgress)
{
return;
} _shutdownInProgress = true; try
{
if (_socket != null)
{
_socket.Close();
}
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{
// TODO: why the swallow?
}
finally
{
_socket = null;
} try
{
if (_host != null)
{
_host.Shutdown();
} // the host is going to raise an event that this class uses to null the field.
// just wait until the field is nulled and continue. while (_host != null)
{
new AutoResetEvent(false).WaitOne();
}
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{
// TODO: what am i afraid of here?
} } //private void TimeOut(object ignored)
//{
// TimeOut();
//} /////<summary>
/////</summary>
//public void TimeOut()
//{
// ShutDown();
// OnTimeOut();
//} //private void OnTimeOut()
//{
// EventHandler handler = TimedOut;
// if (handler != null) handler(this, EventArgs.Empty);
//}
}
}

Server类

//  **********************************************************************************
// CassiniDev - http://cassinidev.codeplex.com
//
// Copyright (c) 2010 Sky Sanders. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is subject to terms and conditions of the Microsoft Public
// License (Ms-PL). A copy of the license can be found in the license.txt file
// included in this distribution.
//
// You must not remove this notice, or any other, from this software.
//
// ********************************************************************************** #region using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Web.UI; #endregion namespace SimpleWebServer
{
internal static class CommonExtensions
{
public static string ConvertToHexView(this byte[] value, int numBytesPerRow)
{
if (value == null) return null; List<string> hexSplit = BitConverter.ToString(value)
.Replace('-', ' ')
.Trim()
.SplitIntoChunks(numBytesPerRow*)
.ToList(); int byteAddress = ;
StringBuilder sb = new StringBuilder(); for (int i = ; i < hexSplit.Count; i++)
{
sb.AppendLine(byteAddress.ToString("X4") + ":\t" + hexSplit[i]);
byteAddress += numBytesPerRow;
} return sb.ToString();
} /// <summary>
/// CassiniDev FIX: #12506
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string GetContentType(string fileName)
{
if (!File.Exists(fileName))
{
return null;
} string contentType; FileInfo info = new FileInfo(fileName);
string extension = info.Extension.ToLowerInvariant(); #region switch filetype
switch (extension)
{
//NOTE: these are fallbacks - and should be refined as needed
// Only if the request does not already know
// the content-type will this switch be hit - meaning that
// served content-types for extensions listed here may not match
// as this method may not be polled. case ".svgz":
contentType = "image/svg+xml";
break; // from registry - last resort - verified mappings follow case ".3g2":
contentType = "video/3gpp2";
break;
case ".3gp":
contentType = "video/3gpp";
break;
case ".3gp2":
contentType = "video/3gpp2";
break;
case ".3gpp":
contentType = "video/3gpp";
break;
case ".adt":
contentType = "audio/vnd.dlna.adts";
break;
case ".amr":
contentType = "audio/AMR";
break;
case ".addin":
contentType = "text/xml";
break;
case ".evr":
contentType = "audio/evrc-qcp";
break;
case ".evrc":
contentType = "audio/evrc-qcp";
break;
case ".ssisdeploymentmanifest":
contentType = "text/xml";
break;
case ".xoml":
contentType = "text/plain";
break;
case ".aac":
contentType = "audio/aac";
break;
case ".ac3":
contentType = "audio/ac3";
break;
case ".accda":
contentType = "application/msaccess";
break;
case ".accdb":
contentType = "application/msaccess";
break;
case ".accdc":
contentType = "application/msaccess";
break;
case ".accde":
contentType = "application/msaccess";
break;
case ".accdr":
contentType = "application/msaccess";
break;
case ".accdt":
contentType = "application/msaccess";
break;
case ".acrobatsecuritysettings":
contentType = "application/vnd.adobe.acrobat-security-settings";
break;
case ".ad":
contentType = "text/plain";
break;
case ".ade":
contentType = "application/msaccess";
break;
case ".adobebridge":
contentType = "application/x-bridge-url";
break;
case ".adp":
contentType = "application/msaccess";
break;
case ".adts":
contentType = "audio/vnd.dlna.adts";
break;
case ".amc":
contentType = "application/x-mpeg";
break;
case ".application":
contentType = "application/x-ms-application";
break;
case ".asa":
contentType = "application/xml";
break;
case ".asax":
contentType = "application/xml";
break;
case ".ascx":
contentType = "application/xml";
break; case ".ashx":
contentType = "application/xml";
break;
case ".asm":
contentType = "text/plain";
break;
case ".asmx":
contentType = "application/xml";
break;
case ".aspx":
contentType = "application/xml";
break;
case ".awf":
contentType = "application/vnd.adobe.workflow";
break;
case ".biz":
contentType = "text/xml";
break; case ".c2r":
contentType = "text/vnd-ms.click2record+xml";
break;
case ".caf":
contentType = "audio/x-caf";
break; case ".cc":
contentType = "text/plain";
break;
case ".cd":
contentType = "text/plain";
break;
case ".cdda":
contentType = "audio/aiff";
break; case ".config":
contentType = "application/xml";
break;
case ".contact":
contentType = "text/x-ms-contact";
break;
case ".coverage":
contentType = "application/xml";
break;
case ".cpp":
contentType = "text/plain";
break;
case ".cs":
contentType = "text/plain";
break;
case ".csdproj":
contentType = "text/plain";
break;
case ".csproj":
contentType = "text/plain";
break;
case ".jar":
contentType = "application/java-archive";
break;
case ".csv":
contentType = "application/vnd.ms-excel";
break;
case ".cur":
contentType = "text/plain";
break;
case ".cxx":
contentType = "text/plain";
break;
case ".datasource":
contentType = "application/xml";
break;
case ".dbproj":
contentType = "text/plain";
break;
case ".dcd":
contentType = "text/xml";
break;
case ".dd":
contentType = "text/plain";
break;
case ".def":
contentType = "text/plain";
break; case ".design":
contentType = "image/design";
break;
case ".dgml":
contentType = "application/xml";
break;
case ".dib":
contentType = "image/bmp";
break;
case ".dif":
contentType = "video/x-dv";
break;
case ".docm":
contentType = "application/vnd.ms-word.document.macroEnabled.12";
break;
case ".docx":
contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
break;
case ".dotm":
contentType = "application/vnd.ms-word.template.macroEnabled.12";
break;
case ".dotx":
contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.template";
break;
case ".dsp":
contentType = "text/plain";
break;
case ".dsprototype":
contentType = "text/plain";
break;
case ".dsw":
contentType = "text/plain";
break;
case ".dtd":
contentType = "application/xml-dtd";
break;
case ".dtsconfig":
contentType = "text/xml";
break;
case ".dv":
contentType = "video/x-dv";
break;
case ".dwfx":
contentType = "model/vnd.dwfx+xps";
break;
case ".easmx":
contentType = "model/vnd.easmx+xps";
break;
case ".edrwx":
contentType = "model/vnd.edrwx+xps";
break;
case ".eprtx":
contentType = "model/vnd.eprtx+xps";
break;
case ".fdf":
contentType = "application/vnd.fdf";
break;
case ".filters":
contentType = "Application/xml";
break;
case ".flc":
contentType = "video/flc";
break;
case ".fo":
contentType = "text/xml";
break;
case ".fsscript":
contentType = "application/fsharp-script";
break;
case ".fsx":
contentType = "application/fsharp-script";
break;
case ".generictest":
contentType = "application/xml";
break;
case ".group":
contentType = "text/x-ms-group";
break;
case ".gsm":
contentType = "audio/x-gsm";
break;
case ".hpp":
contentType = "text/plain";
break;
case ".hxa":
contentType = "application/xml";
break;
case ".hxc":
contentType = "application/xml";
break;
case ".hxd":
contentType = "application/octet-stream";
break;
case ".hxe":
contentType = "application/xml";
break;
case ".hxf":
contentType = "application/xml";
break;
case ".hxh":
contentType = "application/octet-stream";
break;
case ".hxi":
contentType = "application/octet-stream";
break;
case ".hxk":
contentType = "application/xml";
break;
case ".hxq":
contentType = "application/octet-stream";
break;
case ".hxr":
contentType = "application/octet-stream";
break;
case ".hxs":
contentType = "application/octet-stream";
break;
case ".hxt":
contentType = "application/xml";
break;
case ".hxv":
contentType = "application/xml";
break;
case ".hxw":
contentType = "application/octet-stream";
break;
case ".hxx":
contentType = "text/plain";
break;
case ".i":
contentType = "text/plain";
break;
case ".idl":
contentType = "text/plain";
break;
case ".inc":
contentType = "text/plain";
break;
case ".inl":
contentType = "text/plain";
break;
case ".ipproj":
contentType = "text/plain";
break;
case ".iqy":
contentType = "text/x-ms-iqy";
break;
case ".ismv":
contentType = "video/ismv";
break;
case ".jsx":
contentType = "text/plain";
break;
case ".jsxbin":
contentType = "text/plain";
break;
case ".jtx":
contentType = "application/x-jtx+xps";
break;
case ".ldd":
contentType = "text/plain";
break;
case ".library-ms":
contentType = "application/windows-library+xml";
break;
case ".loadtest":
contentType = "application/xml";
break;
case ".lsaprototype":
contentType = "text/plain";
break;
case ".lst":
contentType = "text/plain";
break;
case ".m1v":
contentType = "video/mpeg";
break;
case ".m2t":
contentType = "video/vnd.dlna.mpeg-tts";
break;
case ".m2ts":
contentType = "video/vnd.dlna.mpeg-tts";
break;
case ".m2v":
contentType = "video/mpeg";
break;
case ".m4a":
contentType = "audio/mp4";
break;
case ".m4b":
contentType = "audio/x-m4b";
break;
case ".m4p":
contentType = "audio/x-m4p";
break;
case ".m4v":
contentType = "video/x-m4v";
break;
case ".mac":
contentType = "image/x-macpaint";
break;
case ".mak":
contentType = "text/plain";
break;
case ".map":
contentType = "text/plain";
break;
case ".master":
contentType = "application/xml";
break;
case ".mda":
contentType = "application/msaccess";
break;
case ".mde":
contentType = "application/msaccess";
break;
case ".mdp":
contentType = "text/plain";
break;
case ".mfp":
contentType = "application/x-shockwave-flash";
break;
case ".mk":
contentType = "text/plain";
break;
case ".mod":
contentType = "video/mpeg";
break;
case ".mp2v":
contentType = "video/mpeg";
break;
case ".mp4":
contentType = "video/mp4";
break;
case ".mp4v":
contentType = "video/mp4";
break;
case ".mpf":
contentType = "application/vnd.ms-mediapackage";
break;
case ".mqv":
contentType = "video/quicktime";
break;
case ".mts":
contentType = "video/vnd.dlna.mpeg-tts";
break;
case ".mtx":
contentType = "application/xml";
break;
case ".mxp":
contentType = "application/x-mmxp";
break;
case ".nix":
contentType = "application/x-mix-transfer";
break;
case ".odc":
contentType = "text/x-ms-odc";
break;
case ".odh":
contentType = "text/plain";
break;
case ".odl":
contentType = "text/plain";
break;
case ".odp":
contentType = "application/vnd.oasis.opendocument.presentation";
break;
case ".ods":
contentType = "application/vnd.oasis.opendocument.spreadsheet";
break;
case ".odt":
contentType = "application/vnd.oasis.opendocument.text";
break;
case ".orderedtest":
contentType = "application/xml";
break;
case ".osdx":
contentType = "application/opensearchdescription+xml";
break;
case ".pct":
contentType = "image/pict";
break;
case ".pcx":
contentType = "image/x-pcx";
break; case ".pdfxml":
contentType = "application/vnd.adobe.pdfxml";
break;
case ".pdx":
contentType = "application/vnd.adobe.pdx";
break;
case ".pic":
contentType = "image/pict";
break;
case ".pict":
contentType = "image/pict";
break;
case ".pkgdef":
contentType = "text/plain";
break;
case ".pkgundef":
contentType = "text/plain";
break;
case ".png":
contentType = "image/png";
break;
case ".pnt":
contentType = "image/x-macpaint";
break;
case ".pntg":
contentType = "image/x-macpaint";
break;
case ".potm":
contentType = "application/vnd.ms-powerpoint.template.macroEnabled.12";
break;
case ".potx":
contentType = "application/vnd.openxmlformats-officedocument.presentationml.template";
break;
case ".ppa":
contentType = "application/vnd.ms-powerpoint";
break;
case ".ppam":
contentType = "application/vnd.ms-powerpoint.addin.macroEnabled.12";
break;
case ".ppsm":
contentType = "application/vnd.ms-powerpoint.slideshow.macroEnabled.12";
break;
case ".ppsx":
contentType = "application/vnd.openxmlformats-officedocument.presentationml.slideshow";
break;
case ".pptm":
contentType = "application/vnd.ms-powerpoint.presentation.macroEnabled.12";
break;
case ".pptx":
contentType = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
break;
case ".psc1":
contentType = "application/PowerShell";
break;
case ".psess":
contentType = "application/xml";
break;
case ".pwz":
contentType = "application/vnd.ms-powerpoint";
break;
case ".pxr":
contentType = "image/pxr";
break;
case ".qcp":
contentType = "audio/vnd.qcelp";
break;
case ".qht":
contentType = "text/x-html-insertion";
break;
case ".qhtm":
contentType = "text/x-html-insertion";
break;
case ".qti":
contentType = "image/x-quicktime";
break;
case ".qtif":
contentType = "image/x-quicktime";
break;
case ".qtl":
contentType = "application/x-quicktimeplayer";
break;
case ".rat":
contentType = "application/rat-file";
break;
case ".raw":
contentType = "application/octet-stream";
break; case ".rc":
contentType = "text/plain";
break;
case ".rc2":
contentType = "text/plain";
break;
case ".rct":
contentType = "text/plain";
break;
case ".rdf":
contentType = "text/xml";
break;
case ".rdlc":
contentType = "application/xml";
break;
case ".rels":
contentType = "application/vnd.ms-package.relationships+xml";
break;
case ".resx":
contentType = "application/xml";
break;
case ".rgs":
contentType = "text/plain";
break;
case ".rjt":
contentType = "application/vnd.rn-realsystem-rjt";
break;
case ".rm":
contentType = "application/vnd.rn-realmedia";
break;
case ".rmf":
contentType = "application/vnd.adobe.rmf";
break;
case ".rmj":
contentType = "application/vnd.rn-realsystem-rmj";
break;
case ".rmm":
contentType = "audio/x-pn-realaudio";
break;
case ".rmp":
contentType = "application/vnd.rn-rn_music_package";
break;
case ".rms":
contentType = "application/vnd.rn-realaudio-secure";
break;
case ".rmvb":
contentType = "application/vnd.rn-realmedia-vbr";
break;
case ".rmx":
contentType = "application/vnd.rn-realsystem-rmx";
break;
case ".rnx":
contentType = "application/vnd.rn-realplayer";
break;
case ".rp":
contentType = "image/vnd.rn-realpix";
break;
case ".rpm":
contentType = "audio/x-pn-realaudio-plugin";
break;
case ".rqy":
contentType = "text/x-ms-rqy";
break;
case ".rsml":
contentType = "application/vnd.rn-rsml";
break;
case ".rt":
contentType = "text/vnd.rn-realtext";
break;
case ".rtsp":
contentType = "application/x-rtsp";
break;
case ".ruleset":
contentType = "application/xml";
break;
case ".rv":
contentType = "video/vnd.rn-realvideo";
break;
case ".s":
contentType = "text/plain";
break;
case ".sd":
contentType = "text/plain";
break;
case ".sd2":
contentType = "audio/x-sd2";
break;
case ".sdm":
contentType = "text/plain";
break;
case ".sdmdocument":
contentType = "text/plain";
break;
case ".sdp":
contentType = "application/sdp";
break;
case ".sdv":
contentType = "video/sd-video";
break;
case ".searchConnector-ms":
contentType = "application/windows-search-connector+xml";
break;
case ".settings":
contentType = "application/xml";
break;
case ".sgi":
contentType = "image/x-sgi";
break;
case ".shtml":
contentType = "text/html";
break;
case ".sitemap":
contentType = "application/xml";
break;
case ".skin":
contentType = "application/xml";
break;
case ".sldm":
contentType = "application/vnd.ms-powerpoint.slide.macroEnabled.12";
break;
case ".sldx":
contentType = "application/vnd.openxmlformats-officedocument.presentationml.slide";
break;
case ".slk":
contentType = "application/vnd.ms-excel";
break;
case ".sln":
contentType = "text/plain";
break;
case ".slupkg-ms":
contentType = "application/x-ms-license";
break;
case ".smi":
contentType = "application/smil";
break;
case ".smil":
contentType = "application/smil";
break;
case ".snippet":
contentType = "application/xml";
break;
case ".sol":
contentType = "text/plain";
break;
case ".sor":
contentType = "text/plain";
break;
case ".srf":
contentType = "text/plain";
break;
case ".svc":
contentType = "application/xml";
break;
case ".tga":
contentType = "image/x-targa";
break;
case ".targa":
contentType = "image/x-targa";
break;
case ".testrunconfig":
contentType = "application/xml";
break;
case ".testsettings":
contentType = "application/xml";
break;
case ".thmx":
contentType = "application/vnd.ms-officetheme";
break;
case ".tlh":
contentType = "text/plain";
break;
case ".tli":
contentType = "text/plain";
break;
case ".trx":
contentType = "application/xml";
break;
case ".ts":
contentType = "video/vnd.dlna.mpeg-tts";
break;
case ".tts":
contentType = "video/vnd.dlna.mpeg-tts";
break;
case ".user":
contentType = "text/plain";
break;
case ".vb":
contentType = "text/plain";
break;
case ".vbdproj":
contentType = "text/plain";
break;
case ".vbproj":
contentType = "text/plain";
break;
case ".vcproj":
contentType = "Application/xml";
break;
case ".vcxproj":
contentType = "Application/xml";
break;
case ".vddproj":
contentType = "text/plain";
break;
case ".vdp":
contentType = "text/plain";
break;
case ".vdproj":
contentType = "text/plain";
break;
case ".vdx":
contentType = "application/vnd.visio";
break;
case ".vscontent":
contentType = "application/xml";
break;
case ".vsct":
contentType = "text/xml";
break;
case ".vsd":
contentType = "application/vnd.visio";
break;
case ".vsi":
contentType = "application/ms-vsi";
break;
case ".vsix":
contentType = "application/vsix";
break;
case ".vsixlangpack":
contentType = "text/xml";
break;
case ".vsixmanifest":
contentType = "text/xml";
break;
case ".vsl":
contentType = "application/vnd.visio";
break;
case ".vsmdi":
contentType = "application/xml";
break;
case ".vspscc":
contentType = "text/plain";
break;
case ".vss":
contentType = "application/vnd.visio";
break;
case ".vsscc":
contentType = "text/plain";
break;
case ".vssettings":
contentType = "text/xml";
break;
case ".vssscc":
contentType = "text/plain";
break;
case ".vst":
contentType = "application/vnd.visio";
break;
case ".vstemplate":
contentType = "text/xml";
break;
case ".vsto":
contentType = "application/x-ms-vsto";
break;
case ".vsu":
contentType = "application/vnd.visio";
break;
case ".vsw":
contentType = "application/vnd.visio";
break;
case ".vsx":
contentType = "application/vnd.visio";
break;
case ".vtx":
contentType = "application/vnd.visio";
break;
case ".wax":
contentType = "audio/x-ms-wax";
break;
case ".wbk":
contentType = "application/msword";
break;
case ".wdp":
contentType = "image/vnd.ms-photo";
break;
case ".webtest":
contentType = "application/xml";
break;
case ".wiq":
contentType = "application/xml";
break;
case ".wiz":
contentType = "application/msword";
break;
case ".wm":
contentType = "video/x-ms-wm";
break;
case ".wma":
contentType = "audio/x-ms-wma";
break;
case ".wmd":
contentType = "application/x-ms-wmd";
break;
case ".wmv":
contentType = "video/x-ms-wmv";
break;
case ".wmx":
contentType = "video/x-ms-wmx";
break;
case ".wmz":
contentType = "application/x-ms-wmz";
break;
case ".wpl":
contentType = "application/vnd.ms-wpl";
break;
case ".wsc":
contentType = "text/scriptlet";
break;
case ".wsdl":
contentType = "application/xml";
break;
case ".wvx":
contentType = "video/x-ms-wvx";
break;
case ".xaml":
contentType = "application/xaml+xml";
break;
case ".xbap":
contentType = "application/x-ms-xbap";
break;
case ".xbrl":
contentType = "text/xml";
break;
case ".xdp":
contentType = "application/vnd.adobe.xdp+xml";
break;
case ".xdr":
contentType = "application/xml";
break;
case ".xej":
contentType = "application/xej+xml";
break;
case ".xel":
contentType = "application/xel+xml";
break;
case ".xesc":
contentType = "application/x-ms-wmv";
break;
case ".xfd":
contentType = "application/vnd.adobe.xfd+xml";
break;
case ".xfdf":
contentType = "application/vnd.adobe.xfdf";
break;
case ".xht":
contentType = "application/xhtml+xml";
break;
case ".xhtml":
contentType = "application/xhtml+xml";
break;
case ".xlam":
contentType = "application/vnd.ms-excel.addin.macroEnabled.12";
break;
case ".xlk":
contentType = "application/vnd.ms-excel";
break;
case ".xll":
contentType = "application/vnd.ms-excel";
break;
case ".xlsb":
contentType = "application/vnd.ms-excel.sheet.binary.macroEnabled.12";
break;
case ".xlsm":
contentType = "application/vnd.ms-excel.sheet.macroEnabled.12";
break;
case ".xlsx":
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
break;
case ".xltm":
contentType = "application/vnd.ms-excel.template.macroEnabled.12";
break;
case ".xltx":
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.template";
break;
case ".xml":
contentType = "application/xml";
break;
case ".xmta":
contentType = "application/xml";
break;
case ".xpr":
contentType = "image/xpr";
break;
case ".xps":
contentType = "application/vnd.ms-xpsdocument";
break;
case ".xrm-ms":
contentType = "text/xml";
break;
case ".xsc":
contentType = "application/xml";
break;
case ".xsd":
contentType = "application/xml";
break;
case ".xsl":
contentType = "text/xml";
break;
case ".xslt":
contentType = "application/xml";
break;
case ".xss":
contentType = "application/xml";
break;
case ".323":
contentType = "text/h323";
break;
case ".acx":
contentType = "application/internet-property-stream";
break;
case ".ai":
contentType = "application/postscript";
break;
case ".aif":
contentType = "audio/x-aiff";
break;
case ".aifc":
contentType = "audio/x-aiff";
break;
case ".aiff":
contentType = "audio/x-aiff";
break;
case ".asf":
contentType = "video/x-ms-asf";
break;
case ".asr":
contentType = "video/x-ms-asf";
break;
case ".asx":
contentType = "video/x-ms-asf";
break;
case ".au":
contentType = "audio/basic";
break;
case ".avi":
contentType = "video/x-msvideo";
break;
case ".axs":
contentType = "application/olescript";
break;
case ".bas":
contentType = "text/plain";
break;
case ".bcpio":
contentType = "application/x-bcpio";
break;
case ".bin":
contentType = "application/octet-stream";
break;
case ".bmp":
contentType = "image/bmp";
break;
case ".c":
contentType = "text/plain";
break;
case ".cat":
contentType = "application/vnd.ms-pkiseccat";
break;
case ".cdf":
contentType = "application/x-cdf";
break;
case ".cer":
contentType = "application/x-x509-ca-cert";
break;
case ".class":
contentType = "application/octet-stream";
break;
case ".clp":
contentType = "application/x-msclip";
break;
case ".cmx":
contentType = "image/x-cmx";
break;
case ".cod":
contentType = "image/cis-cod";
break;
case ".cpio":
contentType = "application/x-cpio";
break;
case ".crd":
contentType = "application/x-mscardfile";
break;
case ".crl":
contentType = "application/pkix-crl";
break;
case ".crt":
contentType = "application/x-x509-ca-cert";
break;
case ".csh":
contentType = "application/x-csh";
break;
case ".css":
contentType = "text/css";
break;
case ".dcr":
contentType = "application/x-director";
break;
case ".der":
contentType = "application/x-x509-ca-cert";
break;
case ".dir":
contentType = "application/x-director";
break;
case ".dll":
contentType = "application/x-msdownload";
break;
case ".dms":
contentType = "application/octet-stream";
break;
case ".doc":
contentType = "application/msword";
break;
case ".dot":
contentType = "application/msword";
break;
case ".dvi":
contentType = "application/x-dvi";
break;
case ".dxr":
contentType = "application/x-director";
break;
case ".eps":
contentType = "application/postscript";
break;
case ".etx":
contentType = "text/x-setext";
break;
case ".evy":
contentType = "application/envoy";
break;
case ".exe":
contentType = "application/octet-stream";
break;
case ".fif":
contentType = "application/fractals";
break;
case ".flr":
contentType = "x-world/x-vrml";
break;
case ".gif":
contentType = "image/gif";
break;
case ".gtar":
contentType = "application/x-gtar";
break;
case ".gz":
contentType = "application/x-gzip";
break;
case ".h":
contentType = "text/plain";
break;
case ".hdf":
contentType = "application/x-hdf";
break;
case ".hlp":
contentType = "application/winhlp";
break;
case ".hqx":
contentType = "application/mac-binhex40";
break;
case ".hta":
contentType = "application/hta";
break;
case ".htc":
contentType = "text/x-component";
break;
case ".htm":
contentType = "text/html";
break;
case ".html":
contentType = "text/html";
break;
case ".htt":
contentType = "text/webviewhtml";
break;
case ".ico":
contentType = "image/x-icon";
break;
case ".ief":
contentType = "image/ief";
break;
case ".iii":
contentType = "application/x-iphone";
break;
case ".ins":
contentType = "application/x-internet-signup";
break;
case ".isp":
contentType = "application/x-internet-signup";
break;
case ".jfif":
contentType = "image/pipeg";
break;
case ".jpe":
contentType = "image/jpeg";
break;
case ".jpeg":
contentType = "image/jpeg";
break;
case ".jpg":
contentType = "image/jpeg";
break;
case ".js":
contentType = "application/x-javascript";
break;
case ".latex":
contentType = "application/x-latex";
break;
case ".lha":
contentType = "application/octet-stream";
break;
case ".lsf":
contentType = "video/x-la-asf";
break;
case ".lsx":
contentType = "video/x-la-asf";
break;
case ".lzh":
contentType = "application/octet-stream";
break;
case ".m13":
contentType = "application/x-msmediaview";
break;
case ".m14":
contentType = "application/x-msmediaview";
break;
case ".m3u":
contentType = "audio/x-mpegurl";
break;
case ".man":
contentType = "application/x-troff-man";
break;
case ".mdb":
contentType = "application/x-msaccess";
break;
case ".me":
contentType = "application/x-troff-me";
break;
case ".mht":
contentType = "message/rfc822";
break;
case ".mhtml":
contentType = "message/rfc822";
break;
case ".mid":
contentType = "audio/mid";
break;
case ".mny":
contentType = "application/x-msmoney";
break;
case ".mov":
contentType = "video/quicktime";
break;
case ".movie":
contentType = "video/x-sgi-movie";
break;
case ".mp2":
contentType = "video/mpeg";
break;
case ".mp3":
contentType = "audio/mpeg";
break;
case ".mpa":
contentType = "video/mpeg";
break;
case ".mpe":
contentType = "video/mpeg";
break;
case ".mpeg":
contentType = "video/mpeg";
break;
case ".mpg":
contentType = "video/mpeg";
break;
case ".mpp":
contentType = "application/vnd.ms-project";
break;
case ".mpv2":
contentType = "video/mpeg";
break;
case ".ms":
contentType = "application/x-troff-ms";
break;
case ".msg":
contentType = "application/vnd.ms-outlook";
break;
case ".mvb":
contentType = "application/x-msmediaview";
break;
case ".nc":
contentType = "application/x-netcdf";
break;
case ".nws":
contentType = "message/rfc822";
break;
case ".oda":
contentType = "application/oda";
break;
case ".p10":
contentType = "application/pkcs10";
break;
case ".p12":
contentType = "application/x-pkcs12";
break;
case ".p7b":
contentType = "application/x-pkcs7-certificates";
break;
case ".p7c":
contentType = "application/x-pkcs7-mime";
break;
case ".p7m":
contentType = "application/x-pkcs7-mime";
break;
case ".p7r":
contentType = "application/x-pkcs7-certreqresp";
break;
case ".p7s":
contentType = "application/x-pkcs7-signature";
break;
case ".pbm":
contentType = "image/x-portable-bitmap";
break;
case ".pdf":
contentType = "application/pdf";
break;
case ".pfx":
contentType = "application/x-pkcs12";
break;
case ".pgm":
contentType = "image/x-portable-graymap";
break;
case ".pko":
contentType = "application/ynd.ms-pkipko";
break;
case ".pma":
contentType = "application/x-perfmon";
break;
case ".pmc":
contentType = "application/x-perfmon";
break;
case ".pml":
contentType = "application/x-perfmon";
break;
case ".pmr":
contentType = "application/x-perfmon";
break;
case ".pmw":
contentType = "application/x-perfmon";
break;
case ".pnm":
contentType = "image/x-portable-anymap";
break;
case ".pot":
contentType = "application/vnd.ms-powerpoint";
break;
case ".pot,":
contentType = "application/vnd.ms-powerpoint";
break;
case ".ppm":
contentType = "image/x-portable-pixmap";
break;
case ".pps":
contentType = "application/vnd.ms-powerpoint";
break;
case ".ppt":
contentType = "application/vnd.ms-powerpoint";
break;
case ".prf":
contentType = "application/pics-rules";
break;
case ".ps":
contentType = "application/postscript";
break;
case ".pub":
contentType = "application/x-mspublisher";
break;
case ".qt":
contentType = "video/quicktime";
break;
case ".ra":
contentType = "audio/x-pn-realaudio";
break;
case ".ram":
contentType = "audio/x-pn-realaudio";
break;
case ".ras":
contentType = "image/x-cmu-raster";
break;
case ".rgb":
contentType = "image/x-rgb";
break;
case ".rmi":
contentType = "audio/mid";
break;
case ".roff":
contentType = "application/x-troff";
break;
case ".rtf":
contentType = "application/rtf";
break;
case ".rtx":
contentType = "text/richtext";
break;
case ".scd":
contentType = "application/x-msschedule";
break;
case ".sct":
contentType = "text/scriptlet";
break;
case ".setpay":
contentType = "application/set-payment-initiation";
break;
case ".setreg":
contentType = "application/set-registration-initiation";
break;
case ".sh":
contentType = "application/x-sh";
break;
case ".shar":
contentType = "application/x-shar";
break;
case ".sit":
contentType = "application/x-stuffit";
break;
case ".snd":
contentType = "audio/basic";
break;
case ".spc":
contentType = "application/x-pkcs7-certificates";
break;
case ".spl":
contentType = "application/futuresplash";
break;
case ".src":
contentType = "application/x-wais-source";
break;
case ".sst":
contentType = "application/vnd.ms-pkicertstore";
break;
case ".stl":
contentType = "application/vnd.ms-pkistl";
break;
case ".stm":
contentType = "text/html";
break;
case ".sv4cpio":
contentType = "application/x-sv4cpio";
break;
case ".sv4crc":
contentType = "application/x-sv4crc";
break;
case ".svg":
contentType = "image/svg+xml";
break;
case ".swf":
contentType = "application/x-shockwave-flash";
break;
case ".t":
contentType = "application/x-troff";
break;
case ".tar":
contentType = "application/x-tar";
break;
case ".tcl":
contentType = "application/x-tcl";
break;
case ".tex":
contentType = "application/x-tex";
break;
case ".texi":
contentType = "application/x-texinfo";
break;
case ".texinfo":
contentType = "application/x-texinfo";
break;
case ".tgz":
contentType = "application/x-compressed";
break;
case ".tif":
contentType = "image/tiff";
break;
case ".tiff":
contentType = "image/tiff";
break;
case ".tr":
contentType = "application/x-troff";
break;
case ".trm":
contentType = "application/x-msterminal";
break;
case ".tsv":
contentType = "text/tab-separated-values";
break;
case ".txt":
contentType = "text/plain";
break;
case ".uls":
contentType = "text/iuls";
break;
case ".ustar":
contentType = "application/x-ustar";
break;
case ".vcf":
contentType = "text/x-vcard";
break;
case ".vrml":
contentType = "x-world/x-vrml";
break;
case ".wav":
contentType = "audio/x-wav";
break;
case ".wcm":
contentType = "application/vnd.ms-works";
break;
case ".wdb":
contentType = "application/vnd.ms-works";
break;
case ".wks":
contentType = "application/vnd.ms-works";
break;
case ".wmf":
contentType = "application/x-msmetafile";
break;
case ".wps":
contentType = "application/vnd.ms-works";
break;
case ".wri":
contentType = "application/x-mswrite";
break;
case ".wrl":
contentType = "x-world/x-vrml";
break;
case ".wrz":
contentType = "x-world/x-vrml";
break;
case ".xaf":
contentType = "x-world/x-vrml";
break;
case ".xbm":
contentType = "image/x-xbitmap";
break;
case ".xla":
contentType = "application/vnd.ms-excel";
break;
case ".xlc":
contentType = "application/vnd.ms-excel";
break;
case ".xlm":
contentType = "application/vnd.ms-excel";
break;
case ".xls":
contentType = "application/vnd.ms-excel";
break;
case ".xlt":
contentType = "application/vnd.ms-excel";
break;
case ".xlw":
contentType = "application/vnd.ms-excel";
break;
case ".xof":
contentType = "x-world/x-vrml";
break;
case ".xpm":
contentType = "image/x-xpixmap";
break;
case ".xwd":
contentType = "image/x-xwindowdump";
break;
case ".z":
contentType = "application/x-compress";
break;
case ".zip":
contentType = "application/zip";
break; default:
contentType = "";
break;
}
#endregion return contentType;
} public static T GetValueOrDefault<T>(this IDataRecord row, string fieldName)
{
int ordinal = row.GetOrdinal(fieldName);
return row.GetValueOrDefault<T>(ordinal);
} public static T GetValueOrDefault<T>(this IDataRecord row, int ordinal)
{
return (T) (row.IsDBNull(ordinal) ? default(T) : row.GetValue(ordinal));
} public static byte[] StreamToBytes(this Stream input)
{
int capacity = input.CanSeek ? (int) input.Length : ;
using (MemoryStream output = new MemoryStream(capacity))
{
int readLength;
byte[] buffer = new byte[]; do
{
readLength = input.Read(buffer, , buffer.Length);
output.Write(buffer, , readLength);
} while (readLength != ); return output.ToArray();
}
} private static IList<string> SplitIntoChunks(this string text, int chunkSize)
{
List<string> chunks = new List<string>();
int offset = ;
while (offset < text.Length)
{
int size = Math.Min(chunkSize, text.Length - offset);
chunks.Add(text.Substring(offset, size));
offset += size;
}
return chunks;
}
} /// <summary>
///
/// </summary>
public enum RunState
{
/// <summary>
///
/// </summary>
Idle = ,
/// <summary>
///
/// </summary>
Running
} /// <summary>
///
/// </summary>
public enum PortMode
{
/// <summary>
///
/// </summary>
FirstAvailable = ,
/// <summary>
///
/// </summary>
Specific
} /// <summary>
///
/// </summary>
public enum ErrorField
{
/// <summary>
///
/// </summary>
None,
/// <summary>
///
/// </summary>
ApplicationPath,
/// <summary>
///
/// </summary>
VirtualPath,
/// <summary>
///
/// </summary>
HostName,
/// <summary>
///
/// </summary>
IsAddHost,
/// <summary>
///
/// </summary>
// ReSharper disable InconsistentNaming
IPAddress,
// ReSharper restore InconsistentNaming
/// <summary>
///
/// </summary>
// ReSharper disable InconsistentNaming
IPAddressAny,
// ReSharper restore InconsistentNaming
/// <summary>
///
/// </summary>
// ReSharper disable InconsistentNaming
IPAddressLoopBack,
// ReSharper restore InconsistentNaming
/// <summary>
///
/// </summary>
Port,
/// <summary>
///
/// </summary>
PortRangeStart,
/// <summary>
///
/// </summary>
PortRangeEnd,
/// <summary>
///
/// </summary>
PortRange
} /// <summary>
///
/// </summary>
// ReSharper disable InconsistentNaming
public enum IPMode
// ReSharper restore InconsistentNaming
{
/// <summary>
///
/// </summary>
Loopback = ,
/// <summary>
///
/// </summary>
Any,
/// <summary>
///
/// </summary>
Specific
} /// <summary>
///
/// </summary>
public enum RunMode
{
/// <summary>
///
/// </summary>
Server,
/// <summary>
///
/// </summary>
Hostsfile
} /// <summary>
///
/// </summary>
internal class CassiniException : Exception
{
public CassiniException(string message, ErrorField field, Exception innerException)
: base(message, innerException)
{
Field = field;
} public CassiniException(string message, ErrorField field)
: this(message, field, null)
{
} public ErrorField Field { get; set; }
}
}

Common类

//  **********************************************************************************
// CassiniDev - http://cassinidev.codeplex.com
//
// Copyright (c) 2010 Sky Sanders. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is subject to terms and conditions of the Microsoft Public
// License (Ms-PL). A copy of the license can be found in the license.txt file
// included in this distribution.
//
// You must not remove this notice, or any other, from this software.
//
// ********************************************************************************** #region using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Web; #endregion namespace SimpleWebServer
{
/// <summary>
///
/// </summary>
public class Connection : MarshalByRefObject
{
private const int HttpForbidden = ; // ReSharper disable InconsistentNaming
private const int HttpOK = ;
// ReSharper restore InconsistentNaming private readonly MemoryStream _responseContent;
/// <summary>
///
/// </summary>
public List<string> Plugins = new List<string>();
private readonly Server _server; private Socket _socket; internal Connection(Server server, Socket socket)
{
Plugins = server.Plugins;
Id = Guid.NewGuid();
_responseContent = new MemoryStream();
_server = server;
_socket = socket;
} /// <summary>
///
/// </summary>
public bool Connected
{
get { return _socket.Connected; }
} /// <summary>
///
/// </summary>
public Guid Id { get; private set; } /// <summary>
///
/// </summary>
// ReSharper disable InconsistentNaming
public string LocalIP
// ReSharper restore InconsistentNaming
{
get
{
IPEndPoint ep = (IPEndPoint) _socket.LocalEndPoint;
return (ep != null && ep.Address != null) ? ep.Address.ToString() : "127.0.0.1";
}
} // ReSharper disable InconsistentNaming
/// <summary>
///
/// </summary>
public string RemoteIP
// ReSharper restore InconsistentNaming
{
get
{
IPEndPoint ep = (IPEndPoint) _socket.RemoteEndPoint;
return (ep != null && ep.Address != null) ? ep.Address.ToString() : "127.0.0.1";
}
} /// <summary>
///
/// </summary>
public void Close()
{ try
{
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{
}
finally
{
_socket = null;
}
} /// <summary>
/// </summary>
public override object InitializeLifetimeService()
{
return null;
} /// <summary>
///
/// </summary>
/// <param name="maxBytes"></param>
/// <returns></returns>
public byte[] ReadRequestBytes(int maxBytes)
{
try
{
if (WaitForRequestBytes() == )
{
return null;
} int numBytes = _socket.Available; if (numBytes > maxBytes)
{
numBytes = maxBytes;
} int numReceived = ; byte[] buffer = new byte[numBytes]; if (numBytes > )
{
numReceived = _socket.Receive(buffer, , numBytes, SocketFlags.None);
} if (numReceived < numBytes)
{
byte[] tempBuffer = new byte[numReceived]; if (numReceived > )
{
Buffer.BlockCopy(buffer, , tempBuffer, , numReceived);
} buffer = tempBuffer;
} return buffer;
}
catch
{
return null;
}
} /// <summary>
///
/// </summary>
/// <returns></returns>
public int WaitForRequestBytes()
{
int availBytes = ; try
{
if (_socket.Available == )
{
_socket.Poll(, SelectMode.SelectRead); if (_socket.Available == && _socket.Connected)
{
_socket.Poll(, SelectMode.SelectRead);
}
} availBytes = _socket.Available;
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{
} return availBytes;
} /// <summary>
///
/// </summary>
public void Write100Continue()
{
WriteEntireResponseFromString(, null, null, true);
} internal void Write200Continue()
{
WriteEntireResponseFromString(, null, string.Empty, true);
} /// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
public void WriteBody(byte[] data, int offset, int length)
{
try
{
_responseContent.Write(data, , data.Length);
_socket.Send(data, offset, length, SocketFlags.None);
}
catch (SocketException)
{
}
} /// <summary>
///
/// </summary>
/// <param name="fileName"></param>
/// <param name="keepAlive"></param>
public void WriteEntireResponseFromFile(String fileName, bool keepAlive)
{
if (!File.Exists(fileName))
{
WriteErrorAndClose();
return;
} // Deny the request if the contentType cannot be recognized. string contentType = CommonExtensions.GetContentType(fileName); //TODO: i am pretty sure this is unnecessary
if (contentType == null)
{
WriteErrorAndClose(HttpForbidden);
return;
} string contentTypeHeader = "Content-Type: " + contentType + "\r\n"; bool completed = false;
FileStream fs = null; try
{
fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
int len = (int) fs.Length;
byte[] fileBytes = new byte[len];
int bytesRead = fs.Read(fileBytes, , len); String headers = MakeResponseHeaders(HttpOK, contentTypeHeader, bytesRead, keepAlive);
_socket.Send(Encoding.UTF8.GetBytes(headers)); _socket.Send(fileBytes, , bytesRead, SocketFlags.None); completed = true;
}
catch (SocketException)
{
}
finally
{
if (!keepAlive || !completed)
{
Close();
} if (fs != null)
{
fs.Close();
}
}
} /// <summary>
///
/// </summary>
/// <param name="statusCode"></param>
/// <param name="extraHeaders"></param>
/// <param name="body"></param>
/// <param name="keepAlive"></param>
public void WriteEntireResponseFromString(int statusCode, String extraHeaders, String body, bool keepAlive)
{
try
{
int bodyLength = (body != null) ? Encoding.UTF8.GetByteCount(body) : ;
string headers = MakeResponseHeaders(statusCode, extraHeaders, bodyLength, keepAlive); _socket.Send(Encoding.UTF8.GetBytes(headers + body));
}
catch (SocketException)
{
}
finally
{
if (!keepAlive)
{
Close();
}
}
} /// <summary>
///
/// </summary>
/// <param name="statusCode"></param>
/// <param name="message"></param>
public void WriteErrorAndClose(int statusCode, string message)
{
WriteEntireResponseFromString(statusCode, null, GetErrorResponseBody(statusCode, message), false);
} /// <summary>
///
/// </summary>
/// <param name="statusCode"></param>
public void WriteErrorAndClose(int statusCode)
{
WriteErrorAndClose(statusCode, null);
} /// <summary>
///
/// </summary>
/// <param name="statusCode"></param>
/// <param name="extraHeaders"></param>
public void WriteErrorWithExtraHeadersAndKeepAlive(int statusCode, string extraHeaders)
{
WriteEntireResponseFromString(statusCode, extraHeaders, GetErrorResponseBody(statusCode, null), true);
} /// <summary>
///
/// </summary>
/// <param name="statusCode"></param>
/// <param name="extraHeaders"></param>
public void WriteHeaders(int statusCode, String extraHeaders)
{
string headers = MakeResponseHeaders(statusCode, extraHeaders, -, false); try
{
_socket.Send(Encoding.UTF8.GetBytes(headers));
}
catch (SocketException)
{
}
} private string GetErrorResponseBody(int statusCode, string message)
{
string body = Messages.FormatErrorMessageBody(statusCode, _server.VirtualPath); if (!string.IsNullOrEmpty(message))
{
body += "\r\n<!--\r\n" + message + "\r\n-->";
} return body;
} //private void InitializeLogInfo()
//{
// _requestLog = new LogInfo
// {
// Created = DateTime.Now,
// ConversationId = Id,
// RowType = 1,
// Identity = _server.GetProcessUser(),
// PhysicalPath = _server.PhysicalPath
// }; // _responseLog = new LogInfo
// {
// ConversationId = Id,
// RowType = 2
// };
//} private static string MakeResponseHeaders(int statusCode, string moreHeaders, int contentLength, bool keepAlive)
{
StringBuilder sb = new StringBuilder(); sb.Append("HTTP/1.1 " + statusCode + " " + HttpWorkerRequest.GetStatusDescription(statusCode) + "\r\n");
sb.Append("Server: Cassini/" + Messages.VersionString + "\r\n");
sb.Append("Date: " + DateTime.Now.ToUniversalTime().ToString("R", DateTimeFormatInfo.InvariantInfo) + "\r\n"); if (contentLength >= )
{
sb.Append("Content-Length: " + contentLength + "\r\n");
} if (moreHeaders != null)
{
sb.Append(moreHeaders);
} if (!keepAlive)
{
sb.Append("Connection: Close\r\n");
} sb.Append("\r\n"); return sb.ToString();
}
}
}

Connection类

#region

using System;
using System.Globalization;
using System.Security.Permissions;
using System.Security.Principal;
using System.Threading;
using System.Web;
using System.Web.Hosting; #endregion namespace SimpleWebServer
{
public class Host : MarshalByRefObject, IRegisteredObject
{
private bool _disableDirectoryListing; private string _installPath; private string _lowerCasedClientScriptPathWithTrailingSlash; private string _lowerCasedVirtualPath; private string _lowerCasedVirtualPathWithTrailingSlash; private volatile int _pendingCallsCount; private string _physicalClientScriptPath; private string _physicalPath; private int _port; private bool _requireAuthentication; private Server _server; private string _virtualPath; public AppDomain AppDomain
{
get { return AppDomain.CurrentDomain; }
} public Host()
{
HostingEnvironment.RegisterObject(this);
} public bool DisableDirectoryListing
{
get { return _disableDirectoryListing; }
} public string InstallPath
{
get { return _installPath; }
} public string NormalizedClientScriptPath
{
get { return _lowerCasedClientScriptPathWithTrailingSlash; }
} public string NormalizedVirtualPath
{
get { return _lowerCasedVirtualPathWithTrailingSlash; }
} public string PhysicalClientScriptPath
{
get { return _physicalClientScriptPath; }
} public string PhysicalPath
{
get { return _physicalPath; }
} public int Port
{
get { return _port; }
} public bool RequireAuthentication
{
get { return _requireAuthentication; }
} public string VirtualPath
{
get { return _virtualPath; }
} #region IRegisteredObject Members void IRegisteredObject.Stop(bool immediate)
{
// Unhook the Host so Server will process the requests in the new appdomain. if (_server != null)
{
_server.HostStopped();
} // Make sure all the pending calls complete before this Object is unregistered.
WaitForPendingCallsToFinish(); HostingEnvironment.UnregisterObject(this); Thread.Sleep();
HttpRuntime.Close();
Thread.Sleep();
} #endregion public void Configure(Server server, int port, string virtualPath, string physicalPath,
bool requireAuthentication)
{
Configure(server, port, virtualPath, physicalPath, requireAuthentication, false);
} public void Configure(Server server, int port, string virtualPath, string physicalPath)
{
Configure(server, port, virtualPath, physicalPath, false, false);
} public void Configure(Server server, int port, string virtualPath, string physicalPath,
bool requireAuthentication, bool disableDirectoryListing)
{
_server = server; _port = port;
_installPath = null;
_virtualPath = virtualPath;
_requireAuthentication = requireAuthentication;
_disableDirectoryListing = disableDirectoryListing;
_lowerCasedVirtualPath = CultureInfo.InvariantCulture.TextInfo.ToLower(_virtualPath);
_lowerCasedVirtualPathWithTrailingSlash = virtualPath.EndsWith("/", StringComparison.Ordinal)
? virtualPath
: virtualPath + "/";
_lowerCasedVirtualPathWithTrailingSlash =
CultureInfo.InvariantCulture.TextInfo.ToLower(_lowerCasedVirtualPathWithTrailingSlash);
_physicalPath = physicalPath;
_physicalClientScriptPath = HttpRuntime.AspClientScriptPhysicalPath + "\\";
_lowerCasedClientScriptPathWithTrailingSlash =
CultureInfo.InvariantCulture.TextInfo.ToLower(HttpRuntime.AspClientScriptVirtualPath + "/");
} public SecurityIdentifier GetProcessSid()
{
using (WindowsIdentity identity = new WindowsIdentity(_server.GetProcessToken()))
{
return identity.User;
}
} public IntPtr GetProcessToken()
{
new SecurityPermission(PermissionState.Unrestricted).Assert();
return _server.GetProcessToken();
} public string GetProcessUser()
{
return _server.GetProcessUser();
} public override object InitializeLifetimeService()
{
// never expire the license
return null;
} public bool IsVirtualPathAppPath(string path)
{
if (path == null)
{
return false;
}
path = CultureInfo.InvariantCulture.TextInfo.ToLower(path);
return (path == _lowerCasedVirtualPath || path == _lowerCasedVirtualPathWithTrailingSlash);
} public bool IsVirtualPathInApp(string path, out bool isClientScriptPath)
{
isClientScriptPath = false; if (path == null)
{
return false;
} if (_virtualPath == "/" && path.StartsWith("/", StringComparison.Ordinal))
{
if (path.StartsWith(_lowerCasedClientScriptPathWithTrailingSlash, StringComparison.Ordinal))
{
isClientScriptPath = true;
}
return true;
} path = CultureInfo.InvariantCulture.TextInfo.ToLower(path); if (path.StartsWith(_lowerCasedVirtualPathWithTrailingSlash, StringComparison.Ordinal))
{
return true;
} if (path == _lowerCasedVirtualPath)
{
return true;
} if (path.StartsWith(_lowerCasedClientScriptPathWithTrailingSlash, StringComparison.Ordinal))
{
isClientScriptPath = true;
return true;
} return false;
} public bool IsVirtualPathInApp(String path)
{
bool isClientScriptPath;
return IsVirtualPathInApp(path, out isClientScriptPath);
} public void ProcessRequest(Connection conn,string dfPage)
{
// Add a pending call to make sure our thread doesn't get killed
AddPendingCall(); try
{
new Request(_server, this, conn, dfPage).Process();
}
finally
{
RemovePendingCall();
}
} [SecurityPermission(SecurityAction.Assert, Unrestricted = true)]
public void Shutdown()
{
HostingEnvironment.InitiateShutdown();
} private void AddPendingCall()
{
//TODO: investigate this issue - ref var not volitile
#pragma warning disable 0420
Interlocked.Increment(ref _pendingCallsCount);
#pragma warning restore 0420
} private void RemovePendingCall()
{
//TODO: investigate this issue - ref var not volitile
#pragma warning disable 0420
Interlocked.Decrement(ref _pendingCallsCount);
#pragma warning restore 0420
} private void WaitForPendingCallsToFinish()
{
for (; ; )
{
if (_pendingCallsCount <= )
{
break;
} Thread.Sleep();
}
}
}
}

Host类

//  **********************************************************************************
// CassiniDev - http://cassinidev.codeplex.com
//
// Copyright (c) 2010 Sky Sanders. All rights reserved.
//
// This source code is subject to terms and conditions of the Microsoft Public
// License (Ms-PL). A copy of the license can be found in the license.txt file
// included in this distribution.
//
// You must not remove this notice, or any other, from this software.
//
// ********************************************************************************** #region using System;
using System.Runtime.InteropServices; #endregion namespace SimpleWebServer
{
internal static class Interop
{
#region Structs [DllImport("SECUR32.DLL", CharSet = CharSet.Unicode)]
public static extern int AcceptSecurityContext(ref SecHandle phCredential, IntPtr phContext,
ref SecBufferDesc pInput, uint fContextReq, uint TargetDataRep,
ref SecHandle phNewContext, ref SecBufferDesc pOutput,
ref uint pfContextAttr, ref long ptsTimeStamp); [DllImport("SECUR32.DLL", CharSet = CharSet.Unicode)]
public static extern int AcquireCredentialsHandle(string pszPrincipal, string pszPackage, uint fCredentialUse,
IntPtr pvLogonID, IntPtr pAuthData, IntPtr pGetKeyFn,
IntPtr pvGetKeyArgument, ref SecHandle phCredential,
ref long ptsExpiry); [DllImport("KERNEL32.DLL", CharSet = CharSet.Unicode)]
public static extern int CloseHandle(IntPtr phToken); [DllImport("SECUR32.DLL", CharSet = CharSet.Unicode)]
public static extern int DeleteSecurityContext(ref SecHandle phContext); /// <summary>
/// FIX: #12506
/// </summary>
[DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
public static extern int FindMimeFromData(IntPtr pBC, [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1,
SizeParamIndex = )] byte[] pBuffer, int cbSize,
[MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed,
int dwMimeFlags, out IntPtr ppwzMimeOut, int dwReserved); [DllImport("SECUR32.DLL", CharSet = CharSet.Unicode)]
public static extern int FreeCredentialsHandle(ref SecHandle phCredential); [DllImport("kernel32.dll", EntryPoint = "GetConsoleScreenBufferInfo", SetLastError = true,
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int GetConsoleScreenBufferInfo(int hConsoleOutput,
ref CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo); [DllImport("KERNEL32.DLL", SetLastError = true)]
public static extern IntPtr GetCurrentThread(); [DllImport("kernel32.dll", EntryPoint = "GetStdHandle", SetLastError = true, CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern int GetStdHandle(int nStdHandle); [DllImport("ADVAPI32.DLL", SetLastError = true)]
public static extern bool ImpersonateSelf(int level); [DllImport("ADVAPI32.DLL", SetLastError = true)]
public static extern int OpenThreadToken(IntPtr thread, int access, bool openAsSelf, ref IntPtr hToken); [DllImport("SECUR32.DLL", CharSet = CharSet.Unicode)]
public static extern int QuerySecurityContextToken(ref SecHandle phContext, ref IntPtr phToken); [DllImport("ADVAPI32.DLL", SetLastError = true)]
public static extern int RevertToSelf(); #region Nested type: CONSOLE_SCREEN_BUFFER_INFO public struct CONSOLE_SCREEN_BUFFER_INFO
{
internal COORD dwCursorPosition;
internal COORD dwMaximumWindowSize;
internal COORD dwSize;
internal SMALL_RECT srWindow;
internal Int16 wAttributes;
} #endregion #region Nested type: COORD public struct COORD
{
internal Int16 x;
internal Int16 y;
} #endregion #region Nested type: SecBuffer [StructLayout(LayoutKind.Sequential)]
public struct SecBuffer
{
// ReSharper disable InconsistentNaming
public uint cbBuffer;
public uint BufferType;
public IntPtr pvBuffer;
// ReSharper restore InconsistentNaming
} #endregion #region Nested type: SecBufferDesc [StructLayout(LayoutKind.Sequential)]
public struct SecBufferDesc
{
// ReSharper disable InconsistentNaming
public uint ulVersion;
public uint cBuffers;
public IntPtr pBuffers;
// ReSharper restore InconsistentNaming
} #endregion #region Nested type: SecHandle [StructLayout(LayoutKind.Sequential)]
public struct SecHandle
{
// ReSharper disable InconsistentNaming
public IntPtr dwLower;
public IntPtr dwUpper;
// ReSharper restore InconsistentNaming
} #endregion #region Nested type: SMALL_RECT public struct SMALL_RECT
{
internal Int16 Bottom;
internal Int16 Left;
internal Int16 Right;
internal Int16 Top;
} #endregion #endregion
}
}

Interop

//  **********************************************************************************
// CassiniDev - http://cassinidev.codeplex.com
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is subject to terms and conditions of the Microsoft Public
// License (Ms-PL). A copy of the license can be found in the license.txt file
// included in this distribution.
//
// You must not remove this notice, or any other, from this software.
//
// ********************************************************************************** #region using System.IO;
using System.Text;
using System.Web; #endregion namespace SimpleWebServer
{
/// <summary>
/// TODO: get this into resources
/// </summary>
internal static class Messages
{
private const string _dirListingDirFormat =
@"{0,38:dddd, MMMM dd, yyyy hh:mm tt} &lt;dir&gt; <A href=""{1}/"">{2}</A>
"; private const string _dirListingFileFormat =
@"{0,38:dddd, MMMM dd, yyyy hh:mm tt} {1,12:n0} <A href=""{2}"">{3}</A>
"; private const string _dirListingFormat1 =
@"<html>
<head>
<title>Directory Listing -- {0}</title>
"; private const string _dirListingFormat2 =
@" </head>
<body bgcolor=""white""> <h2> <i>Directory Listing -- {0}</i> </h2></span> <hr width=100% size=1 color=silver> <PRE>
"; private const string _dirListingParentFormat =
@"<A href=""{0}"">[To Parent Directory]</A> "; private const string _httpErrorFormat1 =
@"<html>
<head>
<title>{0}</title>
"; private const string _httpStyle =
@" <style>
body {font-family:""Verdana"";font-weight:normal;font-size: 8pt;color:black;}
p {font-family:""Verdana"";font-weight:normal;color:black;margin-top: -5px}
b {font-family:""Verdana"";font-weight:bold;color:black;margin-top: -5px}
h1 { font-family:""Verdana"";font-weight:normal;font-size:18pt;color:red }
h2 { font-family:""Verdana"";font-weight:normal;font-size:14pt;color:maroon }
pre {font-family:""Lucida Console"";font-size: 8pt}
.marker {font-weight: bold; color: black;text-decoration: none;}
.version {color: gray;}
.error {margin-bottom: 10px;}
.expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
</style>
"; private static readonly string _dirListingTail =
@"</PRE>
<hr width=100% size=1 color=silver> <b>Version Information:</b>&nbsp;CassiniDev Web Server " +
VersionString + @" </font> </body>
</html>
"; private static readonly string _httpErrorFormat2 =
@" </head>
<body bgcolor=""white""> <span><h1>Server Error in '{0}' Application.<hr width=100% size=1 color=silver></h1> <h2> <i>HTTP Error {1} - {2}.</i> </h2></span> <hr width=100% size=1 color=silver> <b>Version Information:</b>&nbsp;CassiniDev Web Server " +
VersionString + @" </font> </body>
</html>
"; public static string VersionString = typeof (Server).Assembly.GetName().Version.ToString(); public static string FormatDirectoryListing(string dirPath, string parentPath, FileSystemInfo[] elements)
{
StringBuilder sb = new StringBuilder(); sb.Append(string.Format(_dirListingFormat1, dirPath));
sb.Append(_httpStyle);
sb.Append(string.Format(_dirListingFormat2, dirPath)); if (parentPath != null)
{
if (!parentPath.EndsWith("/"))
{
parentPath += "/";
} sb.Append(string.Format(_dirListingParentFormat, parentPath));
} if (elements != null)
{
for (int i = ; i < elements.Length; i++)
{
if (elements[i] is FileInfo)
{
FileInfo fi = (FileInfo) elements[i];
sb.Append(string.Format(_dirListingFileFormat,
fi.LastWriteTime, fi.Length, fi.Name, fi.Name));
}
else if (elements[i] is DirectoryInfo)
{
DirectoryInfo di = (DirectoryInfo) elements[i];
sb.Append(string.Format(_dirListingDirFormat,
di.LastWriteTime, di.Name, di.Name));
}
}
} sb.Append(_dirListingTail);
return sb.ToString();
} public static string FormatErrorMessageBody(int statusCode, string appName)
{
string desc = HttpWorkerRequest.GetStatusDescription(statusCode); return string.Format(_httpErrorFormat1, desc)
+ _httpStyle
+ string.Format(_httpErrorFormat2, appName, statusCode, desc);
}
}
}

Messages

//  **********************************************************************************
// CassiniDev - http://cassinidev.codeplex.com
//
// Copyright (c) 2010 Sky Sanders. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is subject to terms and conditions of the Microsoft Public
// License (Ms-PL). A copy of the license can be found in the license.txt file
// included in this distribution.
//
// You must not remove this notice, or any other, from this software.
//
// ********************************************************************************** #region using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Web;
using System.Web.Hosting;
using Microsoft.Win32.SafeHandles;
using System.Security.Principal; #endregion namespace SimpleWebServer
{
public class Request : SimpleWorkerRequest
{
private const int MaxChunkLength = * ; private const int MaxHeaderBytes = * ; private static readonly char[] BadPathChars = new[] { '%', '>', '<', ':', '\\' }; private static readonly string[] DefaultFileNames = new[] { "default.aspx", "default.htm", "default.html" }; private static readonly char[] IntToHex = new[]
{
'', '', '', '', '', '', '', '', '', '', 'a', 'b', 'c', 'd', 'e', 'f'
}; private static readonly string[] RestrictedDirs = new[]
{
"/bin",
"/app_browsers",
"/app_code",
"/app_data",
"/app_localresources",
"/app_globalresources",
"/app_webreferences"
}; private readonly IStackWalk _connectionPermission = new PermissionSet(PermissionState.Unrestricted);
private readonly Host _host;
private readonly Server _server; private string _allRawHeaders; private byte[] _body; private int _bodyLength; private Connection _connection; private int _contentLength; // security permission to Assert remoting calls to _connection
private int _endHeadersOffset; private string _filePath; private byte[] _headerBytes; private List<ByteString> _headerByteStrings; private bool _headersSent; // parsed request data private bool _isClientScriptPath; private string[] _knownRequestHeaders; private string _path; private string _pathInfo; private string _pathTranslated; private string _protocol; private string _queryString;
private byte[] _queryStringBytes; private List<byte[]> _responseBodyBytes; private StringBuilder _responseHeadersBuilder; private int _responseStatus; private bool _specialCaseStaticFileHeaders; private int _startHeadersOffset; private string[][] _unknownRequestHeaders; private string _url; private string _verb; private string _dfPage; public Request(Server server, Host host, Connection connection,string dfPage)
: base(String.Empty, String.Empty, null)
{
_connectionPermission = new PermissionSet(PermissionState.Unrestricted);
_server = server;
_host = host;
_connection = connection;
_dfPage = dfPage;
} public override void CloseConnection()
{
_connectionPermission.Assert();
_connection.Close();
} public override void EndOfRequest()
{
Connection conn = _connection;
if (conn != null)
{
_connection = null;
_server.OnRequestEnd(conn);
} } public override void FlushResponse(bool finalFlush)
{
if (_responseStatus == && !_headersSent && finalFlush && _verb == "GET")
{ // attempt directory listing
if (ProcessDirectoryListingRequest())
{
return;
}
} _connectionPermission.Assert(); if (!_headersSent)
{
_connection.WriteHeaders(_responseStatus, _responseHeadersBuilder.ToString()); _headersSent = true;
}
foreach (byte[] bytes in _responseBodyBytes)
{
_connection.WriteBody(bytes, , bytes.Length);
} _responseBodyBytes = new List<byte[]>(); if (finalFlush)
{
_connection.Close();
}
} public override string GetAppPath()
{
return _host.VirtualPath;
} public override string GetAppPathTranslated()
{
return _host.PhysicalPath;
} public override string GetFilePath()
{
return _filePath;
} public override string GetFilePathTranslated()
{
return _pathTranslated;
} public override string GetHttpVerbName()
{
return _verb;
} public override string GetHttpVersion()
{
return _protocol;
} public override string GetKnownRequestHeader(int index)
{
return _knownRequestHeaders[index];
} public override string GetLocalAddress()
{
_connectionPermission.Assert();
return _connection.LocalIP;
} public override int GetLocalPort()
{
return _host.Port;
} public override string GetPathInfo()
{
return _pathInfo;
} public override byte[] GetPreloadedEntityBody()
{
return _body;
} public override string GetQueryString()
{
return _queryString;
} public override byte[] GetQueryStringRawBytes()
{
return _queryStringBytes;
} public override string GetRawUrl()
{
return _url;
} public override string GetRemoteAddress()
{
_connectionPermission.Assert();
return _connection.RemoteIP;
} public override int GetRemotePort()
{
return ;
} public override string GetServerName()
{
string localAddress = GetLocalAddress();
if (localAddress.Equals("127.0.0.1"))
{
return "localhost";
}
return localAddress;
} public override string GetServerVariable(string name)
{
string processUser = string.Empty;
string str2 = name;
if (str2 == null)
{
return processUser;
}
if (str2 != "ALL_RAW")
{
if (str2 != "SERVER_PROTOCOL")
{
if (str2 == "LOGON_USER")
{
if (GetUserToken() != IntPtr.Zero)
{
processUser = _host.GetProcessUser();
}
return processUser;
}
if ((str2 == "AUTH_TYPE") && (GetUserToken() != IntPtr.Zero))
{
processUser = "NTLM";
}
return processUser;
}
}
else
{
return _allRawHeaders;
}
return _protocol;
} public override string GetUnknownRequestHeader(string name)
{
int n = _unknownRequestHeaders.Length; for (int i = ; i < n; i++)
{
if (string.Compare(name, _unknownRequestHeaders[i][], StringComparison.OrdinalIgnoreCase) == )
{
return _unknownRequestHeaders[i][];
}
} return null;
} public override string[][] GetUnknownRequestHeaders()
{
return _unknownRequestHeaders;
} ///////////////////////////////////////////////////////////////////////////////////////////////
// Implementation of HttpWorkerRequest public override string GetUriPath()
{
return _path;
} public Connection GetConnection()
{
return _connection;
} public override bool HeadersSent()
{
return _headersSent;
} public override bool IsClientConnected()
{
_connectionPermission.Assert();
return _connection.Connected;
} public override bool IsEntireEntityBodyIsPreloaded()
{
return (_contentLength == _bodyLength);
} public override string MapPath(string path)
{
string mappedPath;
bool isClientScriptPath; if (string.IsNullOrEmpty(path) || path.Equals("/"))
{
// asking for the site root
mappedPath = _host.VirtualPath == "/" ? _host.PhysicalPath : Environment.SystemDirectory;
}
else if (_host.IsVirtualPathAppPath(path))
{
// application path
mappedPath = _host.PhysicalPath;
}
else if (_host.IsVirtualPathInApp(path, out isClientScriptPath))
{
if (isClientScriptPath)
{
mappedPath = _host.PhysicalClientScriptPath +
path.Substring(_host.NormalizedClientScriptPath.Length);
}
else
{
// inside app but not the app path itself
mappedPath = _host.PhysicalPath + path.Substring(_host.NormalizedVirtualPath.Length);
}
}
else
{
// outside of app -- make relative to app path
if (path.StartsWith("/", StringComparison.Ordinal))
{
mappedPath = _host.PhysicalPath + path.Substring();
}
else
{
mappedPath = _host.PhysicalPath + path;
}
} mappedPath = mappedPath.Replace('/', '\\'); if (mappedPath.EndsWith("\\", StringComparison.Ordinal) &&
!mappedPath.EndsWith(":\\", StringComparison.Ordinal))
{
mappedPath = mappedPath.Substring(, mappedPath.Length - );
} return mappedPath;
} [AspNetHostingPermission(SecurityAction.Assert, Level = AspNetHostingPermissionLevel.Medium)]
public void Process()
{
// read the request
if (!TryParseRequest())
{
return;
} // 100 response to POST
if (_verb == "POST" && _contentLength > && _bodyLength < _contentLength)
{
_connection.Write100Continue();
}
if (!_host.RequireAuthentication)
{
// special case for client script
if (_isClientScriptPath)
{
_connection.WriteEntireResponseFromFile(
_host.PhysicalClientScriptPath + _path.Substring(_host.NormalizedClientScriptPath.Length), false);
return;
} // deny access to code, bin, etc.
if (IsRequestForRestrictedDirectory())
{
_connection.WriteErrorAndClose();
return;
} // special case for a request to a directory (ensure / at the end and process default documents)
if (ProcessDirectoryRequest())
{
return;
} PrepareResponse(); // Hand the processing over to HttpRuntime
HttpRuntime.ProcessRequest(this);
}
} public override int ReadEntityBody(byte[] buffer, int size)
{
int bytesRead = ; _connectionPermission.Assert();
byte[] bytes = _connection.ReadRequestBytes(size); if (bytes != null && bytes.Length > )
{
bytesRead = bytes.Length;
Buffer.BlockCopy(bytes, , buffer, , bytesRead);
} return bytesRead;
} public override void SendCalculatedContentLength(int contentLength)
{
if (!_headersSent)
{
_responseHeadersBuilder.Append("Content-Length: ");
_responseHeadersBuilder.Append(contentLength.ToString(CultureInfo.InvariantCulture));
_responseHeadersBuilder.Append("\r\n");
}
} public override void SendKnownResponseHeader(int index, string value)
{
if (_headersSent)
{
return;
} switch (index)
{
case HeaderServer:
case HeaderDate:
case HeaderConnection:
// ignore these
return;
case HeaderAcceptRanges:
// FIX: #14359
if (value != "bytes")
{
// use this header to detect when we're processing a static file
break;
}
_specialCaseStaticFileHeaders = true;
return; case HeaderExpires:
case HeaderLastModified:
// FIX: #14359
if (!_specialCaseStaticFileHeaders)
{
// NOTE: Ignore these for static files. These are generated
// by the StaticFileHandler, but they shouldn't be.
break;
}
return; // FIX: #12506
case HeaderContentType: string contentType = null; if (value == "application/octet-stream")
{
// application/octet-stream is default for unknown so lets
// take a shot at determining the type.
// don't do this for other content-types as you are going to
// end up sending text/plain for endpoints that are handled by
// asp.net such as .aspx, .asmx, .axd, etc etc
contentType = CommonExtensions.GetContentType(_pathTranslated);
}
value = contentType ?? value;
break;
} _responseHeadersBuilder.Append(GetKnownResponseHeaderName(index));
_responseHeadersBuilder.Append(": ");
_responseHeadersBuilder.Append(value);
_responseHeadersBuilder.Append("\r\n");
} public void SetResponseHeader(string name, string value)
{
_responseHeadersBuilder.Append(name);
_responseHeadersBuilder.Append(": ");
_responseHeadersBuilder.Append(value);
_responseHeadersBuilder.Append("\r\n");
} public override void SendResponseFromFile(string filename, long offset, long length)
{
if (length == )
{
return;
} FileStream f = null;
try
{
f = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
SendResponseFromFileStream(f, offset, length);
}
finally
{
if (f != null)
{
f.Close();
}
}
} public override void SendResponseFromFile(IntPtr handle, long offset, long length)
{
if (length == )
{
return;
} using (var sfh = new SafeFileHandle(handle, false))
{
using (var f = new FileStream(sfh, FileAccess.Read))
{
SendResponseFromFileStream(f, offset, length);
}
}
} public override void SendResponseFromMemory(byte[] data, int length)
{
if (length > )
{
var bytes = new byte[length]; Buffer.BlockCopy(data, , bytes, , length);
_responseBodyBytes.Add(bytes);
}
} public override void SendStatus(int statusCode, string statusDescription)
{
_responseStatus = statusCode;
} public override void SendUnknownResponseHeader(string name, string value)
{
if (_headersSent)
return; _responseHeadersBuilder.Append(name);
_responseHeadersBuilder.Append(": ");
_responseHeadersBuilder.Append(value);
_responseHeadersBuilder.Append("\r\n");
} private bool IsBadPath()
{
if (_path.IndexOfAny(BadPathChars) >= )
{
return true;
} if (CultureInfo.InvariantCulture.CompareInfo.IndexOf(_path, "..", CompareOptions.Ordinal) >= )
{
return true;
} if (CultureInfo.InvariantCulture.CompareInfo.IndexOf(_path, "//", CompareOptions.Ordinal) >= )
{
return true;
} return false;
} private bool IsRequestForRestrictedDirectory()
{
String p = CultureInfo.InvariantCulture.TextInfo.ToLower(_path); if (_host.VirtualPath != "/")
{
p = p.Substring(_host.VirtualPath.Length);
} foreach (String dir in RestrictedDirs)
{
if (p.StartsWith(dir, StringComparison.Ordinal))
{
if (p.Length == dir.Length || p[dir.Length] == '/')
{
return true;
}
}
} return false;
} private void ParseHeaders()
{
_knownRequestHeaders = new string[RequestHeaderMaximum]; // construct unknown headers as array list of name1,value1,...
var headers = new List<string>(); for (int i = ; i < _headerByteStrings.Count; i++)
{
string s = _headerByteStrings[i].GetString(); int c = s.IndexOf(':'); if (c >= )
{
string name = s.Substring(, c).Trim();
string value = s.Substring(c + ).Trim(); // remember
int knownIndex = GetKnownRequestHeaderIndex(name);
if (knownIndex >= )
{
_knownRequestHeaders[knownIndex] = value;
}
else
{
headers.Add(name);
headers.Add(value);
}
}
} // copy to array unknown headers int n = headers.Count / ;
_unknownRequestHeaders = new string[n][];
int j = ; for (int i = ; i < n; i++)
{
_unknownRequestHeaders[i] = new string[];
_unknownRequestHeaders[i][] = headers[j++];
_unknownRequestHeaders[i][] = headers[j++];
} // remember all raw headers as one string if (_headerByteStrings.Count > )
{
_allRawHeaders = Encoding.UTF8.GetString(_headerBytes, _startHeadersOffset,
_endHeadersOffset - _startHeadersOffset);
}
else
{
_allRawHeaders = String.Empty;
}
} private void ParsePostedContent()
{
_contentLength = ;
_bodyLength = ; string contentLengthValue = _knownRequestHeaders[HeaderContentLength];
if (contentLengthValue != null)
{
try
{
_contentLength = Int32.Parse(contentLengthValue, CultureInfo.InvariantCulture);
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{
}
} if (_headerBytes.Length > _endHeadersOffset)
{
_bodyLength = _headerBytes.Length - _endHeadersOffset; if (_bodyLength > _contentLength)
{
_bodyLength = _contentLength; // don't read more than the content-length
} if (_bodyLength > )
{
_body = new byte[_bodyLength];
Buffer.BlockCopy(_headerBytes, _endHeadersOffset, _body, , _bodyLength);
}
}
} private void ParseRequestLine()
{
ByteString requestLine = _headerByteStrings[];
ByteString[] elems = requestLine.Split(' '); if (elems == null || elems.Length < || elems.Length > )
{
_connection.WriteErrorAndClose();
return;
} _verb = elems[].GetString(); ByteString urlBytes = elems[];
_url = urlBytes.GetString(); _protocol = elems.Length == ? elems[].GetString() : "HTTP/1.0"; // query string int iqs = urlBytes.IndexOf('?');
_queryStringBytes = iqs > ? urlBytes.Substring(iqs + ).GetBytes() : new byte[]; iqs = _url.IndexOf('?');
if (_url == "/" && !String.IsNullOrEmpty(_dfPage))
_path = _dfPage;
else if (iqs > )
{
_path = _url.Substring(, iqs);
_queryString = _url.Substring(iqs + );
}
else
{
_path = _url;
_queryStringBytes = new byte[];
} // url-decode path if (_path.IndexOf('%') >= )
{
_path = HttpUtility.UrlDecode(_path, Encoding.UTF8); iqs = _url.IndexOf('?');
if (iqs >= )
{
_url = _path + _url.Substring(iqs);
}
else
{
_url = _path;
}
} // path info int lastDot = _path.LastIndexOf('.');
int lastSlh = _path.LastIndexOf('/'); if (lastDot >= && lastSlh >= && lastDot < lastSlh)
{
int ipi = _path.IndexOf('/', lastDot);
_filePath = _path.Substring(, ipi);
_pathInfo = _path.Substring(ipi);
}
else
{
_filePath = _path;
_pathInfo = String.Empty;
} _pathTranslated = MapPath(_filePath); } private void PrepareResponse()
{
_headersSent = false;
_responseStatus = ;
_responseHeadersBuilder = new StringBuilder();
_responseBodyBytes = new List<byte[]>(); ProcessPlugins();
} private bool ProcessDirectoryListingRequest()
{
if (_verb != "GET")
{
return false;
} String dirPathTranslated = _pathTranslated; if (_pathInfo.Length > )
{
// directory path can never have pathInfo
dirPathTranslated = MapPath(_path);
} if (!Directory.Exists(dirPathTranslated))
{
return false;
} // get all files and subdirs
FileSystemInfo[] infos = null;
try
{
infos = (new DirectoryInfo(dirPathTranslated)).GetFileSystemInfos();
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{
} // determine if parent is appropriate
string parentPath = null; if (_path.Length > )
{
int i = _path.LastIndexOf('/', _path.Length - ); parentPath = (i > ) ? _path.Substring(, i) : "/";
if (!_host.IsVirtualPathInApp(parentPath))
{
parentPath = null;
}
} _connection.WriteEntireResponseFromString(, "Content-type: text/html; charset=utf-8\r\n",
Messages.FormatDirectoryListing(_path, parentPath, infos),
false);
return true;
} private bool ProcessDirectoryRequest()
{
String dirPathTranslated = _pathTranslated; if (_pathInfo.Length > )
{
// directory path can never have pathInfo
dirPathTranslated = MapPath(_path);
} if (!Directory.Exists(dirPathTranslated))
{
return false;
} // have to redirect /foo to /foo/ to allow relative links to work
if (!_path.EndsWith("/", StringComparison.Ordinal))
{
string newPath = _path + "/";
string location = "Location: " + UrlEncodeRedirect(newPath) + "\r\n";
string body = "<html><head><title>Object moved</title></head><body>\r\n" +
"<h2>Object moved to <a href='" + newPath + "'>here</a>.</h2>\r\n" +
"</body></html>\r\n"; _connection.WriteEntireResponseFromString(, location, body, false);
return true;
} // check for the default file
foreach (string filename in DefaultFileNames)
{
string defaultFilePath = dirPathTranslated + "\\" + filename; if (File.Exists(defaultFilePath))
{
// pretend the request is for the default file path
_path += filename;
_filePath = _path;
_url = (_queryString != null) ? (_path + "?" + _queryString) : _path;
_pathTranslated = defaultFilePath;
return false; // go through normal processing
}
} return false; // go through normal processing
} private void ReadAllHeaders()
{
_headerBytes = null; do
{
if (!TryReadAllHeaders())
{
// something bad happened
break;
}
} while (_endHeadersOffset < ); // found \r\n\r\n } private void Reset()
{
_headerBytes = null;
_startHeadersOffset = ;
_endHeadersOffset = ;
_headerByteStrings = null; _isClientScriptPath = false; _verb = null;
_url = null;
_protocol = null; _path = null;
_filePath = null;
_pathInfo = null;
_pathTranslated = null;
_queryString = null;
_queryStringBytes = null; _contentLength = ;
_bodyLength = ;
_body = null; _allRawHeaders = null;
_unknownRequestHeaders = null;
_knownRequestHeaders = null;
_specialCaseStaticFileHeaders = false;
} private void SendResponseFromFileStream(Stream f, long offset, long length)
{
long fileSize = f.Length; if (length == -)
{
length = fileSize - offset;
} if (length == || offset < || length > fileSize - offset)
{
return;
} if (offset > )
{
f.Seek(offset, SeekOrigin.Begin);
} if (length <= MaxChunkLength)
{
var fileBytes = new byte[(int)length];
int bytesRead = f.Read(fileBytes, , (int)length);
SendResponseFromMemory(fileBytes, bytesRead);
}
else
{
var chunk = new byte[MaxChunkLength];
var bytesRemaining = (int)length; while (bytesRemaining > )
{
int bytesToRead = (bytesRemaining < MaxChunkLength) ? bytesRemaining : MaxChunkLength;
int bytesRead = f.Read(chunk, , bytesToRead); SendResponseFromMemory(chunk, bytesRead);
bytesRemaining -= bytesRead; // flush to release keep memory
if ((bytesRemaining > ) && (bytesRead > ))
{
FlushResponse(false);
}
}
}
} private void SkipAllPostedContent()
{
if ((_contentLength > ) && (_bodyLength < _contentLength))
{
byte[] buffer;
for (int i = _contentLength - _bodyLength; i > ; i -= buffer.Length)
{
buffer = _connection.ReadRequestBytes(i);
if ((buffer == null) || (buffer.Length == ))
{
return;
}
}
}
} /// <summary>
/// TODO: defer response until request is written
/// </summary>
/// <returns></returns>
private bool TryParseRequest()
{
Reset(); ReadAllHeaders(); if (_headerBytes == null || _endHeadersOffset < ||
_headerByteStrings == null || _headerByteStrings.Count == )
{
_connection.WriteErrorAndClose();
return false;
} ParseRequestLine(); // Check for bad path
if (IsBadPath())
{
_connection.WriteErrorAndClose();
return false;
} // Check if the path is not well formed or is not for the current app
if (!_host.IsVirtualPathInApp(_path, out _isClientScriptPath))
{
_connection.WriteErrorAndClose();
return false;
} ParseHeaders(); ParsePostedContent(); return true;
} private bool TryReadAllHeaders()
{
// read the first packet (up to 32K)
byte[] headerBytes = _connection.ReadRequestBytes(MaxHeaderBytes); if (headerBytes == null || headerBytes.Length == )
return false; if (_headerBytes != null)
{
// previous partial read
int len = headerBytes.Length + _headerBytes.Length;
if (len > MaxHeaderBytes)
return false; var bytes = new byte[len];
Buffer.BlockCopy(_headerBytes, , bytes, , _headerBytes.Length);
Buffer.BlockCopy(headerBytes, , bytes, _headerBytes.Length, headerBytes.Length);
_headerBytes = bytes;
}
else
{
_headerBytes = headerBytes;
} // start parsing
_startHeadersOffset = -;
_endHeadersOffset = -;
_headerByteStrings = new List<ByteString>(); // find the end of headers
var parser = new ByteParser(_headerBytes); for (; ; )
{
ByteString line = parser.ReadLine(); if (line == null)
{
break;
} if (_startHeadersOffset < )
{
_startHeadersOffset = parser.CurrentOffset;
} if (line.IsEmpty)
{
_endHeadersOffset = parser.CurrentOffset;
break;
} _headerByteStrings.Add(line);
} return true;
} private static string UrlEncodeRedirect(string path)
{
// this method mimics the logic in HttpResponse.Redirect (which relies on internal methods) // count non-ascii characters
byte[] bytes = Encoding.UTF8.GetBytes(path);
int count = bytes.Length;
int countNonAscii = ;
for (int i = ; i < count; i++)
{
if ((bytes[i] & 0x80) != )
{
countNonAscii++;
}
} // encode all non-ascii characters using UTF-8 %XX
if (countNonAscii > )
{
// expand not 'safe' characters into %XX, spaces to +s
var expandedBytes = new byte[count + countNonAscii * ];
int pos = ;
for (int i = ; i < count; i++)
{
byte b = bytes[i]; if ((b & 0x80) == )
{
expandedBytes[pos++] = b;
}
else
{
expandedBytes[pos++] = (byte)'%';
expandedBytes[pos++] = (byte)IntToHex[(b >> ) & 0xf];
expandedBytes[pos++] = (byte)IntToHex[b & 0xf];
}
} path = Encoding.ASCII.GetString(expandedBytes);
} // encode spaces into %20
if (path.IndexOf(' ') >= )
{
path = path.Replace(" ", "%20");
} return path;
} private void ProcessPlugins()
{
if (_connection.Plugins != null)
{
foreach (string pluginTypeName in _connection.Plugins)
{
// #TODO: maybe keep plugins instantiated in the connection with reflected method cached? Type pluginType = Type.GetType(pluginTypeName);
object plugin = Activator.CreateInstance(pluginType);
MethodInfo pluginMethod = plugin.GetType().GetMethod("ProcessRequest");
pluginMethod.Invoke(plugin, new object[] { this }); }
}
}
#region Nested type: ByteParser internal class ByteParser
{
private readonly byte[] _bytes; private int _pos; public ByteParser(byte[] bytes)
{
_bytes = bytes;
_pos = ;
} public int CurrentOffset
{
get { return _pos; }
} public ByteString ReadLine()
{
ByteString line = null; for (int i = _pos; i < _bytes.Length; i++)
{
if (_bytes[i] == (byte)'\n')
{
int len = i - _pos;
if (len > && _bytes[i - ] == (byte)'\r')
{
len--;
} line = new ByteString(_bytes, _pos, len);
_pos = i + ;
return line;
}
} if (_pos < _bytes.Length)
{
line = new ByteString(_bytes, _pos, _bytes.Length - _pos);
} _pos = _bytes.Length;
return line;
}
} #endregion #region Nested type: ByteString internal class ByteString
{
private readonly byte[] _bytes; private readonly int _length; private readonly int _offset; public ByteString(byte[] bytes, int offset, int length)
{
_bytes = bytes;
_offset = offset;
_length = length;
} public byte[] Bytes
{
get { return _bytes; }
} public bool IsEmpty
{
get { return (_bytes == null || _length == ); }
} public byte this[int index]
{
get { return _bytes[_offset + index]; }
} public int Length
{
get { return _length; }
} public int Offset
{
get { return _offset; }
} public byte[] GetBytes()
{
var bytes = new byte[_length];
if (_length > ) Buffer.BlockCopy(_bytes, _offset, bytes, , _length);
return bytes;
} public string GetString(Encoding enc)
{
if (IsEmpty) return string.Empty;
return enc.GetString(_bytes, _offset, _length);
} public string GetString()
{
return GetString(Encoding.UTF8);
} public int IndexOf(char ch)
{
return IndexOf(ch, );
} public int IndexOf(char ch, int offset)
{
for (int i = offset; i < _length; i++)
{
if (this[i] == (byte)ch) return i;
}
return -;
} public ByteString[] Split(char sep)
{
var list = new List<ByteString>(); int pos = ;
while (pos < _length)
{
int i = IndexOf(sep, pos);
if (i < )
{
break;
} list.Add(Substring(pos, i - pos));
pos = i + ; while (this[pos] == (byte)sep && pos < _length)
{
pos++;
}
} if (pos < _length)
list.Add(Substring(pos)); return list.ToArray();
} public ByteString Substring(int offset, int len)
{
return new ByteString(_bytes, _offset + offset, len);
} public ByteString Substring(int offset)
{
return Substring(offset, _length - offset);
}
} #endregion
}
}

Request

//  **********************************************************************************
// CassiniDev - http://cassinidev.codeplex.com
//
// Copyright (c) 2010 Sky Sanders. All rights reserved.
//
// This source code is subject to terms and conditions of the Microsoft Public
// License (Ms-PL). A copy of the license can be found in the license.txt file
// included in this distribution.
//
// You must not remove this notice, or any other, from this software.
//
// ********************************************************************************** #region using System; #endregion namespace SimpleWebServer
{
///<summary>
///</summary>
public class RequestEventArgs : EventArgs
{
private readonly Guid _id; ///<summary>
///</summary>
///<param name="id"></param>
///<param name="requestLog"></param>
///<param name="responseLog"></param>
public RequestEventArgs(Guid id)
{
_id = id;
} ///<summary>
///</summary>
public Guid Id
{
get { return _id; }
} }
}

RequestEventArgs

代码出自:cassinidev.codeplex.com

Web服务器(CassiniDev的裁减版)的更多相关文章

  1. Nginx 0.8.x + PHP 5.2.13(FastCGI)搭建胜过Apache十倍的Web服务器(第6版)

    前言:本文是我撰写的关于搭建“Nginx + PHP(FastCGI)”Web服务器的第6篇文章.本系列文章作为国内最早详细介绍 Nginx + PHP 安装.配置.使用的资料之一,为推动 Nginx ...

  2. Nginx 0.8.x + PHP 5.2.13(FastCGI)搭建胜过Apache十倍的Web服务器(第6版)(转)

    转自:http://blog.s135.com/nginx_php_v6/] 前言:本文是我撰写的关于搭建“Nginx + PHP(FastCGI)”Web服务器的第6篇文章.本系列文章作为国内最早详 ...

  3. Nginx 0.8.x + PHP 5.2.13(FastCGI)搭建胜过Apache十倍的Web服务器(第6版)[原创]

    mkdir -p /data0/software cd /data0/software wget http://sysoev.ru/nginx/nginx-0.8.46.tar.gz wget htt ...

  4. 手写一个Web服务器,极简版Tomcat

    网络传输是通过遵守HTTP协议的数据格式来传输的. HTTP协议是由标准化组织W3C(World Wide Web Consortium,万维网联盟)和IETF(Internet Engineerin ...

  5. [转]三大WEB服务器对比分析(apache ,lighttpd,nginx)

    原博文地址:http://www.blogjava.net/daniel-tu/archive/2008/12/29/248883.html 一.软件介绍(apache  lighttpd  ngin ...

  6. 三大WEB服务器对比分析(apache ,lighttpd,nginx)

    一.软件介绍(apache  lighttpd  nginx) 1. lighttpd Lighttpd是一个具有非常低的内存开销,cpu占用率低,效能好,以及丰富的模块等特点.lighttpd是众多 ...

  7. [教程]安装青鸟云Web服务器

    青鸟云Web服务器 支持的安装环境: Windows XP (32bit) Windows Server 2003/R2 (32bit) Windows 7 (32/64bit) Windows Se ...

  8. 转: 三大WEB服务器对比分析(apache ,lighttpd,nginx) (2008年的旧文,仅供参考之用)

    from:  http://www.blogjava.net/daniel-tu/archive/2008/12/29/248883.html 三大WEB服务器对比分析(apache ,lighttp ...

  9. (转)三大WEB服务器对比分析(apache ,lighttpd,nginx)

    ref : https://www.iteye.com/blog/hai0378-1860220   一.软件介绍(apache  lighttpd  nginx) 1. lighttpd Light ...

随机推荐

  1. xunsearch迅搜体验

    安装与启动 http://www.xunsearch.com/doc/php/guide/start.installation 编写配置文件 http://www.xunsearch.com/doc/ ...

  2. Android Volley源码分析

    今天来顺手分析一下谷歌的volley http通信框架.首先从github上 下载volley的源码, 然后新建你自己的工程以后 选择import module 然后选择volley. 最后还需要更改 ...

  3. python numpy sum函数用法

    numpy.sum numpy.sum(a, axis=None, dtype=None, out=None, keepdims=False)[source] Sum of array element ...

  4. 更改 input type 的值

    需要实现的效果:一个输入框,当输入框未获得焦点的时候,value 值为 “密码”:当输入框失去焦点的时候,输入内容显示为”*****” <input name=”password” type=” ...

  5. linux下ubuntu系统安装及开发环境配置

    1.安装系统:别的没什么说的,就是安的时候把网线拔了,不然到 configure apt的时候会卡起很久不走的2.配置网络 编辑/etc/network/interface打开/etc/networt ...

  6. [搜片神器]之DHT网络爬虫的C++程序初步开源

    回应大家的要求,特地整理了一开始自己整合的代码,这样最简单,最直接的可以分析流程,至于文章里面提供的程序界面更多,需要大家自己开发. 谢谢园子朋友的支持,已经找到个VPS进行测试,国外的服务器: ht ...

  7. Linux基本命令(10)其他命令

    其他命令 命令 功能 命令 功能 echo 显示一字串 passwd 修改密码 clear 清除显示器 lpr 打印 lpq 查看在打印队列中等待的作业 lprm 取消打印队列中的作业 10.1 ec ...

  8. 建立连接ALM的xml config文件

    我就不贴所有的了,如果有谁想要所有源码和应用程序,可以密我 这里我贴下如何在第一次运行的时候自动建立一个ALMConfig的xml文件 private static void CreateALMCon ...

  9. slowhttps安装及使用心得

    运行及安装环境,kali. 到googlecode上下载安装包,cd到安装目录./configure 运行完毕后输入make 结束后make install 简单点就直接apt-get install ...

  10. Monitor traffic to localhost from IE or .NET

    原文:http://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/MonitorLocalTraffic Monitor traffic to lo ...