Originally I was intrigued what it would take to write a simple webserver. But
as I progressed I realized that a tiny web server could be quite
useful for a number of applications that need to serve specialized
web pages and where the overhead of writing an ASP.NET application is not
warranted (or where it is not possible to host ASP.NET).
A good example is a news aggregator, which serves a single page containing the
current news feeds. This is included as an example in this project.
Using the code
The core of the application is the class TinyServer. This class provides a
simple web server that only supports GET requests (no forms) and serves web
pages from a directory.
To run the sample webserver, you need to build the WebServer project and
configure its App.Config file.
<add key="WebRoot" value="E:\src\DotNet\WebServer\root" />
<!-- location of the web pages to serve -->
<add key="Default" value="default.html" />
<!-- name of the default page -->
<add key="TemplatePath" value="E:\src\DotNet\WebServer\html" />
<!-- location of special templates -->
<add key="Port" value="81" />
<!-- Port to server on -->
<add key="LogFile" value="" />
<!-- filepath, set to "" for console logging -->
<add key="LogLevel" value="All" />
<!--All, Warning, Error, None -->
Once the webServer application starts it instantiates TinyServer and calls
This spins off the server in a separate thread. Calling
Building your own WebServer
Most likely you would want to build your own version of this webserver. You
need to subclass TinyServer and then override the necessary functions. The most
important to override is the method
. In this method you can interrogate the GET command and send back anything
that is necessary.
This is the default implementation:
protected virtual void doGet(string argument)
string url = getUrl(argument);
url = url.Substring(1);
if (url.Length == 0)
url = defaultPageName;
string path = Path.Combine(webRootPath, url);
sendError(404, "File Not Found");
To implement your version there are a number of utility functions at hand:
string getUrl(string argument)
takes the command parameter of doGet and extracts the URL
string  urlArgs
returns a list of arguments that suceeded the URL
sends the OK header. This is necessary before you send any HTML
sendError(int errornr, string errorMsg)
sends an error instead of the OK
sendString(string) sends a message
sends a whole file
sendTemplate (templateName) sends a file in the template directory
The RssAggregator Sample Application
To demonstrate this ability I have written a simple news aggregator that
regularly downloads the RSS feeds from the sources.
The RssAggregator does two things:
download and keep up to date a list of selected RSS Feeds
run a web server that returns a web page containing the feed detail.
The first part uses the RssReader class created by smallguy78. It runs in its
own thread and will download feeds once the current copy is older than one
The second part is implemented by a subclass of TinyServer called AggServer.
AggServer only ever returns one page that contains the newsfeeds abstracts and
links to the articles. So the
doGet() is pretty dumb:
protected override void doGet(string argument)
The smarts to create the webpage is in the method
in turn relies on helper function
whole example (excluding RssReader) just takes 80 lines of code.
Points of Interest
smallguy78 whose RssReader code I used. You can find more
about it in this
RSS Reader article
I am a Software Engineer/Consultant. My work is focussed on helping teams to get more out of their work. So I teach how to do requirements, analysis and design in a format that is easy to understand and apply.
I help with testing too, from starting developers on automated unit testing to running whole testing teams and how they cooperate with development.
For really big projects I provide complete methodologies that support all of the lifecycle.
For relaxation I paddle a sea kayak around Sydney and the Central Coast or write utilities on rainy days to make my life easier.