Web Server In 50 Lines
Web servers are useful, but not always you want or can install and configure one. Here’s a self contained, functional, multi-threaded and extensible web server in just few lines of C#.
1 using System;
2 using System.IO;
3 using System.Net;
4 using System.Text;
5
6
7 class Server {
8
9 static String root = "/home/you/web/root/";
10
11 static String prefix = "http://localhost:8000/";
12
13 static void Main(String[] args) {
14 using (var http = new HttpListener()) {
15 http.Prefixes.Add(prefix);
16 http.Start();
17 while (http.IsListening) {
18 var callback = new AsyncCallback(dispatch);
19 var result = http.BeginGetContext(callback, http);
20 result.AsyncWaitHandle.WaitOne();
21 }
22 }
23 }
24
25 static void dispatch(IAsyncResult result) {
26 var http = (HttpListener)result.AsyncState;
27 var context = http.EndGetContext(result);
28 using (var responseStream = new MemoryStream()) {
29 var localPath = Path.Combine(root, context.Request.Url.LocalPath.Substring(1));
30 if (File.Exists(localPath)) {
31 using (var file = File.OpenRead(localPath)) {
32 file.CopyTo(responseStream);
33 }
34 }
35 else {
36 var text = Encoding.UTF8.GetBytes("404");
37 responseStream.Write(text, 0, text.Length);
38 }
39 context.Response.ContentLength64 = responseStream.Length;
40 responseStream.WriteTo(context.Response.OutputStream);
41 context.Response.OutputStream.Close();
42 }
43 }
44 }
So, you start up a HttpListener and pass every request it receives to dispatch(), there you can get a context that holds a HttpRequest and a HttpResponse, that you know and love, from there on, you’re free on how exactly you create the response, I check, if the requested URL can be mapped to a file, if so, I return that file, if not, I simply write “404”. That should give you a good idea, on how to expand this to match your needs.
Works quite well in my experience. One thing you have to be careful about, is exceptions in dispatch(), as they are in a new thread, you obviously won’t see them in Main().
