incremental
diff --git a/src/base64.cpp b/src/base64.cpp
index 001a467..13ab822 100644
--- a/src/base64.cpp
+++ b/src/base64.cpp
@@ -2,7 +2,7 @@
 #include <cassert>
 
 namespace base64 {
-bool base64_encode(const gsl::cstring_span<> &input, std::string &output) {
+bool base64_encode(const std::string &input, std::string &output) {
   static const char encoding_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
   unsigned int input_length = input.size();
@@ -50,7 +50,7 @@
   return true;
 }
 
-bool base64_decode(const gsl::cstring_span<> &input, std::string &output) {
+bool base64_decode(const std::string &input, std::string &output) {
   static const char nop = -1;
   static const char decoding_data[] = {
       nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
diff --git a/src/token_authorization_middleware.cpp b/src/token_authorization_middleware.cpp
index aeef58c..3a92218 100644
--- a/src/token_authorization_middleware.cpp
+++ b/src/token_authorization_middleware.cpp
@@ -13,10 +13,21 @@
 void TokenAuthorizationMiddleware::context::set_cookie(const std::string& key, const std::string& value) { cookies_to_push_to_client.emplace(key, value); }
 
 void TokenAuthorizationMiddleware::before_handle(crow::request& req, response& res, context& ctx) {
+  return;
+  
   auto return_unauthorized = [&req, &res]() {
     res.code = 401;
     res.end();
   };
+  if (req.url == "/" || boost::starts_with(req.url, "/static/")){
+    //TODO this is total hackery to allow the login page to work before the user
+    // is authenticated.  Also, it will be quite slow for all pages.
+    // Ideally, this should be done in the url router handler, with tagged routes
+    // for the whitelist entries.
+    return;
+  }
+
+  //TODO this
   if (req.url == "/login") {
   }
   // Check for an authorization header, reject if not present
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 32c5d35..b89c2a6 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -1,7 +1,6 @@
 #include "crow/ci_map.h"
 #include "crow/http_parser_merged.h"
 #include "crow/query_string.h"
-//#include "crow/TinySHA1.hpp"
 #include "crow/app.h"
 #include "crow/common.h"
 #include "crow/dumb_timer_queue.h"
@@ -31,23 +30,108 @@
 
 #include <webassets.hpp>
 
+crow::ssl_context_t get_ssl_context(std::string ssl_pem_file){
+  crow::ssl_context_t m_ssl_context{boost::asio::ssl::context::sslv23};
+  m_ssl_context.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3 |
+                            boost::asio::ssl::context::single_dh_use | boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1);
+
+  // m_ssl_context.set_verify_mode(boost::asio::ssl::verify_peer);
+  m_ssl_context.use_certificate_file(ssl_pem_file, boost::asio::ssl::context::pem);
+  m_ssl_context.use_private_key_file(ssl_pem_file, boost::asio::ssl::context::pem);
+
+  // Set up EC curves to auto (boost asio doesn't have a method for this)
+  // There is a pull request to add this.  Once this is included in an asio drop, use the right way
+  // http://stackoverflow.com/questions/18929049/boost-asio-with-ecdsa-certificate-issue
+  if (SSL_CTX_set_ecdh_auto(m_ssl_context.native_handle(), 1) != 1) {
+    CROW_LOG_ERROR << "Error setting tmp ecdh list\n";
+  }
+
+  // From mozilla "compatibility"
+  std::string ciphers =
+      //"ECDHE-ECDSA-CHACHA20-POLY1305:"
+      //"ECDHE-RSA-CHACHA20-POLY1305:"
+      //"ECDHE-ECDSA-AES128-GCM-SHA256:"
+      //"ECDHE-RSA-AES128-GCM-SHA256:"
+      //"ECDHE-ECDSA-AES256-GCM-SHA384:"
+      //"ECDHE-RSA-AES256-GCM-SHA384:"
+      //"DHE-RSA-AES128-GCM-SHA256:"
+      //"DHE-RSA-AES256-GCM-SHA384:"
+      //"ECDHE-ECDSA-AES128-SHA256:"
+      //"ECDHE-RSA-AES128-SHA256:"
+      //"ECDHE-ECDSA-AES128-SHA:"
+      //"ECDHE-RSA-AES256-SHA384:"
+      //"ECDHE-RSA-AES128-SHA:"
+      //"ECDHE-ECDSA-AES256-SHA384:"
+      //"ECDHE-ECDSA-AES256-SHA:"
+      //"ECDHE-RSA-AES256-SHA:"
+      //"DHE-RSA-AES128-SHA256:"
+      //"DHE-RSA-AES128-SHA:"
+      //"DHE-RSA-AES256-SHA256:"
+      //"DHE-RSA-AES256-SHA:"
+      //"ECDHE-ECDSA-DES-CBC3-SHA:"
+      //"ECDHE-RSA-DES-CBC3-SHA:"
+      //"EDH-RSA-DES-CBC3-SHA:"
+      "AES128-GCM-SHA256:"
+      "AES256-GCM-SHA384:"
+      "AES128-SHA256:"
+      "AES256-SHA256:"
+      "AES128-SHA:"
+      "AES256-SHA:"
+      "DES-CBC3-SHA:"
+      "!DSS";
+
+  // From mozilla "modern"
+  std::string modern_ciphers =
+      "ECDHE-ECDSA-AES256-GCM-SHA384:"
+      "ECDHE-RSA-AES256-GCM-SHA384:"
+      "ECDHE-ECDSA-CHACHA20-POLY1305:"
+      "ECDHE-RSA-CHACHA20-POLY1305:"
+      "ECDHE-ECDSA-AES128-GCM-SHA256:"
+      "ECDHE-RSA-AES128-GCM-SHA256:"
+      "ECDHE-ECDSA-AES256-SHA384:"
+      "ECDHE-RSA-AES256-SHA384:"
+      "ECDHE-ECDSA-AES128-SHA256:"
+      "ECDHE-RSA-AES128-SHA256";
+
+  if (SSL_CTX_set_cipher_list(m_ssl_context.native_handle(), ciphers.c_str()) != 1) {
+    CROW_LOG_ERROR << "Error setting cipher list\n";
+  }
+  return m_ssl_context;
+}
+
+
 int main(int argc, char** argv) {
-  auto worker = g3::LogWorker::createLogWorker();
+  auto worker(g3::LogWorker::createLogWorker());
+
+  //TODO rotating logger isn't working super well
+  //auto logger = worker->addSink(std::make_unique<LogRotate>("webserverlog", "/tmp/"),
+  //                              &LogRotate::save);
+
   auto handle = worker->addDefaultLogger(argv[0], "/tmp/");
   g3::initializeLogging(worker.get());
-  auto log_file_name = handle->call(&g3::FileSink::fileName);
   auto sink_handle = worker->addSink(std::make_unique<crow::ColorCoutSink>(), &crow::ColorCoutSink::ReceiveLogMessage);
 
-  LOG(DEBUG) << "Logging to " << log_file_name.get() << "\n";
-
   std::string ssl_pem_file("server.pem");
   ensuressl::ensure_openssl_key_present_and_valid(ssl_pem_file);
 
+  //crow::App<crow::TokenAuthorizationMiddleware> app;
   crow::App<crow::TokenAuthorizationMiddleware> app;
-
   crow::webassets::request_routes(app);
 
-  crow::logger::setLogLevel(crow::LogLevel::DEBUG);
+  crow::logger::setLogLevel(crow::LogLevel::INFO);
 
-  app.port(18080).run();
+  auto rules = app.get_rules();
+  for (auto& rule : rules) {
+    LOG(DEBUG) << "Static route: " << rule;
+  }
+
+  CROW_ROUTE(app, "/routes")
+  ([&app]() {
+    crow::json::wvalue routes;
+
+    routes["routes"] = app.get_rules();
+    return routes;
+  });
+
+  app.port(18080).ssl(std::move(get_ssl_context(ssl_pem_file))).run();
 }