Today I want to write about small class library I wrote some times ago. It is the compact web server written in C#. Class library implements functionality of the single threaded web server, which can run in Windows CE powered system as well as desktop version of Microsoft Windows. Currently only the GET method is supported, but it's possible to pass query strings and process 'em in custom code. Let's see some examples.

Configuring web server

Configuration for web server is stored in WebServerConfiguration class. Here it's possible to setup server root, listening port, IP address etc.. Important thing is the possibility to configure default files like default.html, index.html or other. Do not forget to register MIME types for files that will be handled by the web server. Setting right mime types is necessary for correct response header of the server.

Special files are those files, that need to be treat in custom method and not just send to the client. CompactWeb server supports virtual directories so you can request directory placed outside the server root.

WebServerConfiguration webConf = new WebServerConfiguration();

webConf.IPAddress = IPAddress.Any;
webConf.Port = 80;

// Folder where the web is stored
webConf.ServerRoot = @"\Inetpub";

webConf.AddDefaultFile("default.html");
webConf.AddMimeType(".htm", "text/html");
webConf.AddMimeType(".html", "text/html");
webConf.AddMimeType(".png", "image/png");
webConf.AddMimeType(".jpg", "image/jpg");
webConf.AddMimeType(".gif", "image/gif");
webConf.AddMimeType(".bmp", "image/bmp");
webConf.AddMimeType(".cgi", "text/html");

// .cgi files will be special handled
webConf.AddSpecialFileType(".cgi");

// Register virtual directory
webConf.AddVirtualDirectory("photos", @"\My Documents\Photos");
Necessary step is to setup server root physically in the file system. Simply create the folder and put the website in. file system server root

Start me up

Starting the web server is the easiest thing in whole process. Registering OnLogEvent is fine to track client connections, response sending and exceptions. OnSpecialFileType is raised whenever the file registered as special is requested by client. Delegate for this event can handle output to the client.
webServer = new WebServer(webConf);
webServer.OnLogEvent += new WebServer.LogEvent(webServer_OnLogEvent);
webServer.OnSpecialFileType += new WebServer.SpecialFileType(webServer_OnSpecialFileType);
webServer.Start();
From here, your server is running and ready to serve all files placed in the server root. sample server home page

ASP, PHP, CGI whatever you want

If it's necessary to process some files in special way, you can use delegate to OnSpecialFileType and take the control over processing. Next piece of code handles file with .cgi extension. It takes the content of the file and replace <%=RESULT%> pattern with parameter userName passed in the query string. In case that you will call following URL http://127.0.0.1/form.cgi?userNamer=Joshua the <%=RESULT%> pattern will be replaced with Joshua.
void webServer_OnSpecialFileType(CompactWeb.WebRequest webRequest, out IO.Stream outputStream)
{
outputStream = new MemoryStream();

if (webRequest.FileName == "form.cgi")
{
// Read the requested file template
FileStream sourceFile = new FileStream(webRequest.FullPath, FileMode.Open);
StreamReader streamReader = new StreamReader(sourceFile);
string response = streamReader.ReadToEnd();
streamReader.Close();
sourceFile.Close();

// Parse query string into NameValueCollection
NameValueCollection query = WebServer.ParseQueryString(webRequest.QueryString);

// Replace <%=RESULT%> with the username
string userName = query["userName"];
response = response.Replace("<%=RESULT%>", userName);

// Creat response
byte[] buffer = Encoding.ASCII.GetBytes(response);
outputStream.Write(buffer, 0, buffer.Length);
}
}
file system server root

Download and Conclusion

Complete CompactWeb class library with this sample code is possible to download here CompactWebServer.zip . Even if the code is written in compact framework it can be compiled and used with full version of .NET framework. Usage is NOT limited to windows mobile. Feel free to suggest any ideas and improvements, or change the code for your needs. I believe that you will find this library useful.