"Linux Gazette...making Linux just a little more fun!"

Micro web server: how to save CPU time and hard disk space

Introduction

A personal web server. Today, almost any Linux user has one. Some folks do really
serve content with them; others use it for development of PHP or CGI programs.
Others like me just have it to read the documentation via the browser and to
play with it.
I decided that running the Apache web server is
overkill for my personal applications. Currently I have access to a CGI and
PHP capable provider so I do not need support for these on my own machine. Just plain
serving of files without having to run a huge Apache binary in background.

As a result, I decided to drop running my own Apache web server in favor of
having a simple micro web server that only answers requests when there are any.
It saves me some disk space and RAM, although that wasn't really a significant factor
since my computer has plenty of capacity. Mostly
I wanted to play around with new software and nifty small but usable solutions.

What do I exactly want to do with my web server?

Just a few ordinary things, nothing involving PHP or CGI:

serving a few static files and downloads to my friends

read my package documentation through http

This leads to another important thing: at least some sort of directory indexing
must be supported by the web server. That is, if the final URL component is a directory,
redirect to that directory (add the final slash), then serve up the index.html in that
directory. (The redirect is important so that relative links on the page will function
correctly.) Although this can be done with automated scripts run by cronjobs.
But I prefer a simple builtin solution. It doesn't have to be as complex as the
Apache indexing function although that one is very nice indeed.

In short: I can use almost any web server that supports the http protocol but it doesn't need many fancy features.

Do I need extensive configuration?

In fact no. All of these can be accomplished by symlinking external pieces into the web server's root directory.
No need for "Alias" directives or other complicated options. Just the web server root and I'm happy. Perhaps customizing the port the web server listens on.

But nothing more. A simple command line like this one should be sufficient for my purpose: "binary /path/to/webserver/root".

Standalone server or called via TCP wrapper?

I decided to use a TCP wrapper solution. The web server binary gets only called when there really is a request. No need to mess around
with init scripts. Just a simple line in /etc/inetd.conf and off we go.

However such a solution is not very performant. In fact, if you plan to have more than a few sporadic accesses to your server, go for a
standalone server that runs all the time.

micro_httpd

Beside a few really awkward solutions ( there are web servers written in Java, bash or awk out there), I decided to go for a compilable
solution.

I found a web server called micro_httpd at http://www.acme.com/software/micro_httpd/.
This one is written in plain C, takes just around 150 lines of code and does exactly what I want. Runnable from TCP wrapper, no CGI nor PHP, plain serving of files with indexing capability.

I just added a few more mime types in the code and it worked out of the box.

Grab the sources of micro_http and unpack them.

tar xvzf micro_http.tar.gz

cd micro_httpd

rework the source the file if needed, tweak the #define directives to suite your needs

make

su -c "make install"

And now you should have a binary called micro_httpd in /usr/local/sbin/.

Become root and edit /etc/initd.conf with your favorite editor.
Add a line

Make sure to substitute "/var/httpd/wwwroot/ in the example above with the correct path to your new document root.

Substitute the wwwrun with any valid user account, preferably one that has almost no rights on the system for security reasons.

Now try it out: put a few html files in your new WWW root and make them readable by the user account specified.
Then point your favorite browser to http://localhost/. You should get either an automated index or your index.html file.

Got this far? Great, your small and micro web server is up and running.

Note:The TCP wrapper does log all connects to the server to /var/log/messages. But don't expect a complete Apache-style log from it.
Just plain lines like this:

micro_httpd[886]: connect from x.x.x.x (x.x.x.x)

However with knowledge of the http protocol and the code it should be possible to code an advanced logging facility. I leave that one up to you.

In general, any web server that can be run from inetd can be setup like this one. So look around at Freshmeat.

Conclusion

If your needs are as simple as that, it takes a few minutes to switch from Apache to such a minimalistic solution.

It works pretty good although I'm aware that this solution will fail if there are too many requests. For a simple personal web server
without heavy traffic it should be sufficient.

At least I'm a bit happier now. Decide - perhaps such a solution would suit your needs as well?

[There's also Tux, a micro web server in a Linux kernel module. It works similar
to micro_http, and can chain to a bulkier web server for URLs it can't handle
(e.g., CGI scripts). But note that Tux and micro_http serve different niches.
Tux is for high-traffic sites that serve lots of simple files (e.g., images) and
must keep per-request overhead low to avoid overloading the system. micro_http
via inetd is for sites with light web traffic, where the greater overhead of running
a separate process for each request is overshadowed by the
no overhead at all when there are no requests. Of course, both
micro_http and Tux serve a third niche: nifty small usable solutions you can play
with. Or as LG contributing editor Dan Wilder would say, "small sharp tools that
each do one thing well in the honorable UNIX toolbox tradition."

For more information about Tux, see
Red Hat's Tux 2.1 manual.
I thought Tux was in the standard kernel but I can't find it in 2.4.17, so you'll
have to look around for it.
-Iron.]

Matthias Arndt

I'm a Linux enthusiast from northern Germany.
I like plain old fifties rock'n'roll music, writing
stories and publishing in the Linux Gazette, of course.
Currently I'm studying computer science in conjunction with
economics.