Simple-Web-Server

From Bitpost wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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.