A File Server in C++

Writing a cross-platform HTTP file server in C++ is not a simple task. Back in the days of C++03 it was particularly difficult as the standard library was very limited.

Some of the requirements for writing a HTTP server are:

  • Sockets
  • Cryptographically secure random number generate
  • Threads and thread synchronisation
  • File access

Any POSIX based system will provide these requirements, as will the Win32 API. However, accessing these features requires platform-specific code.

It is natural to try to rely on the standard library as much as possible to reduce the amount of platform-specific code. However, this can catch you out. For example, the rand() function behaves differently on different platforms. On Linux (using the g++ compiler), rand() will preserve its seed even when called from different threads. On Windows (using Visual Studio), each thread has its own seed, so it’s very easy to end up generating the same ‘random’ number for each HTTP request!

Similarly for std::fstream. On Linux, filenames are treated as UTF8 encoded, whereas on Windows, they are treated as ANSI.

This is where C++11 and C++17 come to the rescue. Thankfully we now have the following:

  • std::thread
  • std::random_device
  • std::filesystem

Inspired by these new features, I decided to put all these together to create a simple HTTP file server.

Here is the link to github:

Sadly, the C++ standard library is still lacking sockets, so I had to resort to using native sockets API.