Simple-Web-Server

From Bitpost wiki

The best C++ https code I found during my 2016/08 search. Ole Christian Eidheim, the author, is great, he answered my emails and accepted my pull requests.

Updated code on 2019/01/18

Not much change, it moved to GitLab, cool. I cloned it, and had to make some small tweaks to make the GitLab CI tester happy.

Repo usage

  • I have a GitLab clone with my changes made in branch moodboom-quick-http.
  • my Simple-Web-Server git hook on bitpost:
   🌵 m@bitpost  [~/development/Libraries/c++/Simple-Web-Server.git] cat hooks/post-receive 
   #!/bin/bash

   # MDM WHEN WE RECEIVE CHANGES, AUTOMATICALLY PUSH THEM ALONG TO GITHUB

   branch_name=`git symbolic-ref --short HEAD` 
   retcode=$?
   non_push_suffix="_local"

   # Only push if branch_name was found (my be empty if in detached head state)
   if [ $retcode = 0 ] ; then
       #Only push if branch_name does not end with the non-push suffix
       if $branch_name != *$non_push_suffix  ; then
           echo
           echo "**** Pushing current branch $branch_name to origin [ie gitlab]"
           echo
           git push origin $branch_name;
       fi
   fi
  • and my .git/config
   🌵 m@bitpost  [~/development/Libraries/c++/Simple-Web-Server.git] cat config
   [core]
       repositoryformatversion = 0
       filemode = true
       bare = true
   [remote "origin"]
       url = git@gitlab.com:moodboom/Simple-Web-Server.git
       fetch = +refs/*:refs/*
       mirror = true

Usage

  • SWS uses regex to match requests to handlers, look here to debug when they don't match up as expected:
SWS/server_http.hpp ~ln 348
     void find_resource(const std::shared_ptr<socket_type> &socket, const std::shared_ptr<Request> &request) {
         //Find path- and method-match, and call write_response
bk:      for(auto &regex_method: resource) {
               auto it=regex_method.second.find(request->method);
               if(it!=regex_method.second.end()) {
bk:                REGEX_NS::smatch sm_res;
                   if(REGEX_NS::regex_match(request->path, sm_res, regex_method.first)) {
                       request->path_match=std::move(sm_res);
                       write_response(socket, request, it->second);

Security Concerns

  • I'm contributing to keep SWS ciphers etc. up-to-date so it can maintain an A on its ssl tests.
  • This blog entry has been kept up to date with recommendations and solutions.
  • Use nothing older than tlsv12. Pull request applied, fixed.
  • Use AES not RC4. This requires setting OpenSSL options. Ole advised on how to update the ciphers. I'm investigating.
  • Need HSTS headers to allow perfect forward secrecy.

Repo structure

  • upstream
  • my fork
  • my bare shared mirror of my fork: bitpost: development/thedigitalage/Simple-Web-Server.git
  • my dev clones: development/thedigitalage/Simple-Web-Server
  • to get upstream changes, first make sure you have a dev repo configured to do the work:
cd development/thedigitalage/Simple-Web-Server # any dev clone will do
# make sure it has the upstream available - only do this once
git remote add eidheim-upstream https://github.com/eidheim/Simple-Web-Server.git

Now you can fetch changes and get them merged:

git fetch eidheim-upstream
git checkout master 
git rebase eidheim-upstream/master # rebase your branch, so upstream is preserved even if there are commits (there should NOT be!)
git push

Push them from bitpost up to GitHub:

cd development/thedigitalage/Simple-Web-Server.git
git push 
  • to put together a pull request to send to Ole, first get all upstream changes, then create a new branch off of my fork's master, push the new branch to my fork, and use GitHub to create the pull request
# follow above steps to ensure my fork has latest changes from Ole; then...
git checkout master && git pull
git checkout -b new-feature-name
# work work work
git push --set-upstream origin new-feature-name
# use GitHub to create a pull request

AES discussion

eidheim commented 3 hours ago I found only this: https://github.com/zaphoyd/websocketpp/blob/master/examples/echo_server_tls/echo_server_tls.cpp#L124. Here OpenSSL is used directly to disable RC4 I think (...:!RC4:...). See here for documentation of the command: https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_set_cipher_list.html. The SSL_CTX* is reached by doing context.native_handle() in https_server.hpp if I'm not mistaken. Although which ciphers should be included otherwise I'm not sure of, however, it should be possible to receive the cipher list from SSL_CTX_get_ciphers (https://www.openssl.org/docs/manmaster/ssl/SSL_get_ciphers.html), that is instead of hardcoding them like in https://github.com/zaphoyd/websocketpp/blob/master/examples/echo_server_tls/echo_server_tls.cpp#L124. @moodboom

moodboom commented 3 hours ago Cool. Here's the analysis that led me to think AES was the correct choice:

https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/

I'll try hardcoding a recommended cipher from there as the default and see what I get. If that works, maybe we can provide a cipher option to the user?

Including support for HSTS seems to be the other important concern.