mini_httpd - small HTTP server
Fetch the software.
mini_httpd is a small HTTP server.
Its performance is not great, but for low or medium traffic sites it's
It implements all the basic features of an HTTP server, including:
- GET, HEAD, and POST methods.
- Basic authentication.
- Security against ".." filename snooping.
- The common MIME types.
- Trailing-slash redirection.
- index.html, index.htm, index.cgi
- Directory listings.
- Multihoming / virtual hosting.
- Standard logging.
- Custom error pages.
It can also be configured to do SSL/HTTPS and IPv6.
mini_httpd was written for a couple reasons.
One, as an experiment to see just how slow an old-fashioned forking web
server would be with today's operating systems.
The answer is, surprisingly, not that slow - on FreeBSD 3.2, mini_httpd
benchmarks at about 90% the speed of Apache.
The other main reason for writing mini_httpd was to get a simple platform
for experimenting with new web server technology, for instance SSL.
Are you using mini_httpd?
There's a mailing list:
On Red Hat Linux systems you can use RPM to install mini_httpd, like so:
rpm -ta mini_httpd-1.28.tar.gz
rpm -i /usr/src/redhat/RPMS/i386/mini_httpd-1.28-1.i386.rpm
New in version 1.28:
- Fix to buffer overrun bug in htpasswd. Reported by Alessio Santoru as CVE-2017-17663.
- Some fixes to keep connections from getting stuck forever in FIN_WAIT_2 state.
New in version 1.27:
Fixed bug that prevented binary CGI results from working.
This bug was introduced in 1.23.
Noticed and diagnosed by Qipeng Zhang.
New in version 1.26:
Long-standing bug on FreeBSD using http but not https.
Files were getting truncated at 1MB.
This was due to improper usage of sendfile(2), and not
testing the http path since I only use mini_httpd for
Since Linux has a completely different sendfile(2) call,
it was not affected.
And since https does not use sendfile(2), it also was not
New in version 1.25:
- Improvements to the FreeBSD startup script. (Craig Leres)
- Improvement to SSL support.
New in version 1.24:
- Disable SSLv2 to prevent DROWN attack.
- Fix binary POST request reading. (Erik Waling)
New in version 1.23:
- Fixed CVE-2015-1548, a buffer overflow via snprintf.
New in version 1.22:
- Don't do TCP_NOPUSH on SSL connections. It doesn't help and causes problems.
- Use memmove() for self-overlapping string copies instead of strcpy().
New in version 1.21:
- Disable SSL 3 because of the "poodle" attack.
New in version 1.20:
- Better handling for very large files.
- Use TCP_CORK if it's available and TCP_NOPUSH is not.
- Ignore ECONNABORTED on accept().
- Removed mailto: link from the default index page.
Allow CGIs to provide both Location and Status headers. (A. Skrobov)
- Better logic for figuring out CGI SERVER_NAME environment variable. (Oleg)
- Updated for clang, and general cleanup.
New in version 1.19:
- Prohibit "Host: ." and "Host: .." (David Leadbeater).
Use the specified charset in directory listings and errors
Close and re-open the log file on SIGHUP.
This includes code to chown the log file when starting up as root
so that after switching uids to nobody (or whatever user you
configure) it can still be re-opened.
And there's also code to tweak the logfile pathname after a chroot
so that it still works.
Generate multiple MIME encodings in the correct order, and with
the correct separator.
Re-wrote the read() and write() loops to handle EINTR and EAGAIN.
- Save and restore errno in signal handlers.
Corrected possible buffer overflow in building CGI environment
Simplified handling of HAVE_INT64T (Trisk).
If this causes problems, e.g. if there are still systems which don't
have "long long", we can back out the change.
- Automatically add no-cache control header on error responses.
New in version 1.18:
- Added a bunch of MIME types.
- Allow blank lines in the config file.
- Digital Unix 4.0d doesn't have int64_t.
- Use unsigned short consistently for port number.
- Prohibit slashes in the Host: header (Marcus Breiing).
For some reason there was never a timeout on writing the response, only
on reading the request; fixed.
- Don't send Content-Length header on 304 Not Modified responses.
Allow user-agent log entries to be up to 200 characters long, instead
only of 80.
- Changed most uses of \r and \n to \015 and \012 (Jens Bauer).
Got rid of extra slash in PATH_TRANSLATED (Benedikt Hochstrasser).
New in version 1.17:
- Simplified the IPv6 ifdefs.
- Remove /./ in de_dotdot() (Dana Dahlstrom).
Added an madvise(MADV_SEQUENTIAL) call for the cases that use mmap().
Added .xhtml and .xht to mime_types.txt (suggested by Dave Hodder).
Made the list of possible index filenames into an array instead
- Added a bunch of syslogs.
- On generated pages which set BGCOLOR, also set TEXT LINK and VLINK.
- Added some OpenOffice MIME types (Dave Hodder).
New in version 1.16:
Some fixes for unusual cases in the CGI file-descriptor shuffling
- On SysV use sigset() instead of signal() (David Koblas).
- Set up accept filters after listen() (Kris Spinka).
Preserve query string when doing a missing-slash directory redirect.
- New port.h defines for NetBSD.
Fix for security hole that exposed contents of .htpasswd in some
cases (noticed by email@example.com).
- Allow (and ignore) extra fields in .htpasswd files.
- Added PATH_INFO to CGI environment (Benedikt Hochstrasser).
- Close log file before running CGI (Damien Miller).
- Integrated directory lister (Damien Miller).
- Added a shutdown() call to cgi_interpose_output().
- Added some Microsoft MIME types (Kevin Day).
Use binary search to figure MIME types (suggested by Sascha Schumann
and Rob Ekl).
- Linux's sendfile has a different calling sequence.
- Set TCP_NOPUSH socket option.
- Switch htpasswd from using tmpnam to mkstemp.
- Use memmove instead of memcpy.
- Fix to de_dotdot (Mark Dunlap).
- Added portability defines for Digital Unix.
- Off-by-one error in base-64 decoding (Archie Cobbs).
- URL-encoding in directory listings.
Fix (harmless) subprocess SEGV on null requests (noticed by
Ignore EINTR on select call when doing IPv4 and IPv6 (noticed by Tyler Mitchell).
- Added -V version flag.
- Added a timeout on request reading.
- Corrected some uses of size_t and off_t.
- Now able to serve files larger than 2GB.
Default installation direction is now /usr/local/sbin, not
Added a scripts subdirectory with some sample code for FreeBSD systems.
- Added a -P flag for setting the P3P header.
- Added a -C config-file option similar to thttpd's.
- Added flags to specify the SSL certificate file and cipher set.
Simplified the OS-detection ifdef maze in port.h (Damien Miller).
- Split match() into a separate file, like it is in thttpd.
- Added non-local referer filtering similar to thttpd's.
- Implemented content-encoding header.
- Added rudimentary option to set cache-control headers.
New in version 1.15c:
- Fix for the garbage characters after POST data hack.
New in version 1.15b:
- Fix syntax oops when SSL is defined.
New in version 1.15:
- Update SSL support to current version of OpenSSL.
Close extraneous file descriptors on CGI calls - from Russell Dill.
Hack to deal with garbage characters after POST data generated by
- Use sendfile() if available.
- Use accept filters if available.
New in version 1.14:
- Added hack to prevent MSIE 5 from censoring error messages.
- IPv6/Linux fix from Tero Pelander.
- Documented the -D flag.
New in version 1.13:
- Added some MIME types to support WAP/WML.
Made MIME text character-set an option, with iso-8859-1 the default.
New in version 1.12:
Fix for directory indexes on Linux - symlinks were not indexing right
due to a bug in Linux's ls.
Solaris/SysV fix - it was exitting after serving a single request, due
to SIGCHLD generating an EINTR.
A change in the way wildcard matching works - now a single * only
matches strings that don't include a slash.
To match entire pathnames including slashes you have to use **.
Fix for index.cgi - it was returning the file's contents instead
of running it.
On systems with IPv6, automatically bind to both v4 and v6 sockets.
- Added charset=iso-8859-1 to text MIME types.
New in version 1.11:
- Portability fix for Debian, which lacks gai_strerror().
- Couple of CGI tweaks from David Chaiken.
- A change to SIGPIPE handling.
New in version 1.10:
- Support for filenames with spaces in them.
- Use standard isxdigit macro instead of is_hexit routine.
New in version 1.09:
- IPv6 support.
- Fix to If-Modified-Since - some leap year problems.
- New version of match().
- Minor fix to the page returned by authentication.
New in version 1.08:
- Custom error pages.
- Better ".." handling.
- Disallow listing of virtual host directory.
New in version 1.07:
- Fix for remote-user logging.
New in version 1.06:
Security fix to directory indexing, for dirs with a single quote.
New in version 1.05:
Minor fix to the directory indexing to handle dirs that start
with a tilde.
New in version 1.04:
Tweak chroot() and setuid() calls, so that the username to
switch uids to gets looked up before the chroot().
New in version 1.03:
Bugfix for CGI header parsing - if the CGI was sending binary data
(e.g. images), the result could get truncated or corrupted.
New in version 1.02:
- Bugfix for CGI header parsing.
- Call setlogin() if it's available.
New in version 1.01:
- CGI header parsing.
- If-Modified-Since / 304.
New in version 1.00:
ACME Labs / Software / mini_httpd