From 272697d9e5d34d0dc0f5082a60abe312c6325ca6 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sat, 19 May 2018 13:38:44 +0200 Subject: [PATCH] Addes SSL Support --- Makefile | 2 +- src/client.cpp | 55 ++++++++++++++++++++++++++++++++++++----- src/necronda-server.cpp | 16 +++++++++++- 3 files changed, 65 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index c283ef9..cdf4be3 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ install: @echo "Start compiling..." - g++ src/necronda-server.cpp -o bin/necronda-server -std=c++17 -fPIC -pthread -lz -lmagic + g++ src/necronda-server.cpp -o bin/necronda-server -std=c++17 -fPIC -pthread -lz -lmagic -lssl -ldl -lcrypto @echo "Finished compiling!" diff --git a/src/client.cpp b/src/client.cpp index 0985e04..a234e74 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -67,6 +67,7 @@ bool connection_handler(const char *prefix, Socket socket, long id, long num) { FILE *file = path.openFile(); if (file == nullptr) { + req.setField("Cache-Control", "public, max-age=60"); req.respond(404); } else { string type = path.getFileType(); @@ -98,17 +99,50 @@ bool connection_handler(const char *prefix, Socket socket, long id, long num) { if (invalidMethod) { req.respond(405); } else { + bool compress = type.find("text/") == 0 && req.isExistingField("Accept-Encoding") && req.getField("Accept-Encoding").find("deflate") != string::npos; - req.respond(200, file, compress); + + if (req.isExistingField("Range")) { + string range = req.getField("Range"); + if (range.find("bytes=") != 0 || !path.isStatic()) { + req.respond(416); + } else { + fseek(file, 0L, SEEK_END); + long len = ftell(file); + fseek(file, 0L, SEEK_SET); + long p = range.find('-'); + if (p == string::npos) { + req.respond(416); + } else { + string part1 = range.substr(6, p - 6); + string part2 = range.substr(p + 1, range.length() - p - 1); + long num1 = stol(part1, nullptr, 10); + long num2 = len - 1; + if (!part2.empty()) { + num2 = stol(part2, nullptr, 10); + } + if (num1 < 0 || num1 >= len || num2 < 0 || num2 >= len) { + req.respond(416); + } else { + req.setField("Content-Range", (string) "bytes " + to_string(num1) + "-" + to_string(num2) + "/" + to_string(len)); + req.respond(206, file, compress, num1, num2); + } + } + } + } else { + req.respond(200, file, compress); + } } } + fclose(file); } - - HttpStatusCode status = req.getStatusCode(); - log(prefix, to_string(status.code) + " " + status.message + " (" + formatTime(req.getDuration()) + ")"); } + HttpStatusCode status = req.getStatusCode(); + log(prefix, to_string(status.code) + " " + status.message + " (" + formatTime(req.getDuration()) + ")"); } catch (char *msg) { + HttpStatusCode status = req.getStatusCode(); + log(prefix, to_string(status.code) + " " + status.message + " (" + formatTime(req.getDuration()) + ")"); try { if (msg == "timeout") { log(prefix, "Timeout!"); @@ -190,14 +224,23 @@ void client_handler(Socket *socket, long id) { err = true; } + try { + if (socket->getSocketPort() == 443) { + socket->sslHandshake("/home/lorenz/Documents/Projects/Necronda-Server/necronda-server-3.0/privkey.pem", + "/home/lorenz/Documents/Projects/Necronda-Server/necronda-server-3.0/fullchain.pem"); + } + } catch (char *msg) { + log(prefix, (string) "Unable to perform handhsake: " + msg); + err = true; + } + long reqnum = 0; if (!err) { while (connection_handler(prefix, *socket, id, ++reqnum)); reqnum--; } - log(prefix, - "Connection terminated (#:" + to_string(reqnum) + ", R:, S:, T: " + formatTime(socket->getDuration()) + ")"); + log(prefix, "Connection terminated (#:" + to_string(reqnum) + ", R:, S:, T: " + formatTime(socket->getDuration()) + ")"); socket->close(); } diff --git a/src/necronda-server.cpp b/src/necronda-server.cpp index fc901fe..dea0f9e 100644 --- a/src/necronda-server.cpp +++ b/src/necronda-server.cpp @@ -11,10 +11,14 @@ #include #include #include +#include +#include using namespace std; + + /** * Returns UNIX time in microseconds * @return UNIX time [µs] @@ -48,6 +52,8 @@ string getMimeType(string path) { } } + magic_close(magic); + return type + "; charset=" + charset; } @@ -115,9 +121,17 @@ string getWebRoot(string host) { long clientnum = 0; int main() { + + SSL_load_error_strings(); + SSL_library_init(); + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); + + signal(SIGPIPE, SIG_IGN); + cout << "Necronda Server 3.0" << endl << "by Lorenz Stechauner" << endl << endl; - unsigned short PORT = 8080; + unsigned short PORT = 443; Socket *s; try {