From 8a7b381d63178c1ffd57ec758b6f6a5618c9f83a Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Wed, 17 Jun 2020 11:54:09 +0200 Subject: [PATCH] Replaced tabs with spaces --- src/URI.cpp | 246 ++++---- src/URI.h | 42 +- src/client.cpp | 836 ++++++++++++++-------------- src/necronda-server.cpp | 334 +++++------ src/network/Address.cpp | 34 +- src/network/Address.h | 14 +- src/network/Socket.cpp | 806 +++++++++++++-------------- src/network/Socket.h | 142 ++--- src/network/http/Http.cpp | 26 +- src/network/http/HttpConnection.cpp | 246 ++++---- src/network/http/HttpConnection.h | 40 +- src/network/http/HttpHeader.cpp | 96 ++-- src/network/http/HttpHeader.h | 28 +- src/network/http/HttpRequest.cpp | 86 +-- src/network/http/HttpRequest.h | 38 +- src/network/http/HttpResponse.cpp | 30 +- src/network/http/HttpResponse.h | 36 +- src/network/http/HttpStatusCode.cpp | 92 +-- src/network/http/HttpStatusCode.h | 8 +- src/procopen.cpp | 46 +- src/procopen.h | 8 +- 21 files changed, 1617 insertions(+), 1617 deletions(-) diff --git a/src/URI.cpp b/src/URI.cpp index 9ff361e..83d15fa 100644 --- a/src/URI.cpp +++ b/src/URI.cpp @@ -7,188 +7,188 @@ using namespace std; string getExtension(string path) { - long pos = path.find_last_of('.'); - if (pos == string::npos) { - return ""; - } - return path.substr(pos + 1, path.length() - pos); + long pos = path.find_last_of('.'); + if (pos == string::npos) { + return ""; + } + return path.substr(pos + 1, path.length() - pos); } string getFilename(string path) { - long pos = path.find_last_of('/'); - if (pos == string::npos) { - return ""; - } - return path.substr(pos + 1, path.length() - pos); + long pos = path.find_last_of('/'); + if (pos == string::npos) { + return ""; + } + return path.substr(pos + 1, path.length() - pos); } bool isDirectory(string path) { - struct stat statbuf; - return stat(path.c_str(), &statbuf) == 0 && S_ISDIR(statbuf.st_mode) != 0; + struct stat statbuf; + return stat(path.c_str(), &statbuf) == 0 && S_ISDIR(statbuf.st_mode) != 0; } bool isFile(string path) { - struct stat statbuf; - return stat(path.c_str(), &statbuf) == 0 && S_ISDIR(statbuf.st_mode) == 0; + struct stat statbuf; + return stat(path.c_str(), &statbuf) == 0 && S_ISDIR(statbuf.st_mode) == 0; } bool fileExists(string path) { - struct stat statbuf; - return stat(path.c_str(), &statbuf) == 0; + struct stat statbuf; + return stat(path.c_str(), &statbuf) == 0; } URI::URI(string webroot, string reqpath) { - unsigned long pos = reqpath.find('?'); - if (pos != string::npos) { - queryinit = true; - query = reqpath.substr(pos + 1, reqpath.length() - pos); - reqpath.erase(pos, reqpath.length() - pos); - } else { - query = ""; - queryinit = false; - } - if (webroot.length() >= 1 && webroot[webroot.length() - 1] == '/') { - webroot.erase(webroot.length() - 1); - } - reqpath = url_decode(reqpath); - if (reqpath.find("/../") != string::npos) { - throw (char *) "Invalid path"; - } - if (reqpath[0] != '/') { - reqpath = '/' + reqpath; - } - this->webroot = webroot; - this->reqpath = reqpath; + unsigned long pos = reqpath.find('?'); + if (pos != string::npos) { + queryinit = true; + query = reqpath.substr(pos + 1, reqpath.length() - pos); + reqpath.erase(pos, reqpath.length() - pos); + } else { + query = ""; + queryinit = false; + } + if (webroot.length() >= 1 && webroot[webroot.length() - 1] == '/') { + webroot.erase(webroot.length() - 1); + } + reqpath = url_decode(reqpath); + if (reqpath.find("/../") != string::npos) { + throw (char *) "Invalid path"; + } + if (reqpath[0] != '/') { + reqpath = '/' + reqpath; + } + this->webroot = webroot; + this->reqpath = reqpath; - info = ""; - relpath = reqpath; + info = ""; + relpath = reqpath; - while ((!fileExists(webroot + relpath) || (isDirectory(webroot + relpath) && !fileExists(webroot + relpath + "/index.php"))) - && (!fileExists(webroot + relpath + ".php") || (isDirectory(webroot + relpath + ".php") && !fileExists(webroot + relpath + ".php/index.php"))) - && (!fileExists(webroot + relpath + ".html") || (isDirectory(webroot + relpath + ".html") && !fileExists(webroot + relpath + ".html/index.php")))) { - long slash = relpath.find_last_of('/'); - if (slash == string::npos || relpath == "/") { - break; - } - info = relpath.substr(slash) + info; - relpath.erase(slash); - } + while ((!fileExists(webroot + relpath) || (isDirectory(webroot + relpath) && !fileExists(webroot + relpath + "/index.php"))) + && (!fileExists(webroot + relpath + ".php") || (isDirectory(webroot + relpath + ".php") && !fileExists(webroot + relpath + ".php/index.php"))) + && (!fileExists(webroot + relpath + ".html") || (isDirectory(webroot + relpath + ".html") && !fileExists(webroot + relpath + ".html/index.php")))) { + long slash = relpath.find_last_of('/'); + if (slash == string::npos || relpath == "/") { + break; + } + info = relpath.substr(slash) + info; + relpath.erase(slash); + } - if (!info.empty() && isDirectory(webroot + relpath)) { - relpath.append("/"); - } + if (!info.empty() && isDirectory(webroot + relpath)) { + relpath.append("/"); + } - string abs = relpath; - if (fileExists(webroot + abs)) { - string ext = getExtension(abs); - if (ext == "php" || ext == "html") { - abs.erase(abs.length() - ext.length() - 1, abs.length()); - } - } + string abs = relpath; + if (fileExists(webroot + abs)) { + string ext = getExtension(abs); + if (ext == "php" || ext == "html") { + abs.erase(abs.length() - ext.length() - 1, abs.length()); + } + } - string fname = getFilename(abs); - if (fname == "index") { - abs.erase(abs.length() - fname.length() - 1, abs.length()); - } + string fname = getFilename(abs); + if (fname == "index") { + abs.erase(abs.length() - fname.length() - 1, abs.length()); + } - this->filepath = webroot + relpath; + this->filepath = webroot + relpath; - if (isDirectory(webroot + abs)) { - if (abs[abs.length() - 1] != '/') { - abs += "/"; - } - this->relpath = abs; - abs += "index"; - if (fileExists(webroot + abs + ".php")) { - this->filepath = webroot + abs + ".php"; - } else if (fileExists(webroot + abs + ".html")) { - this->filepath = webroot + abs + ".html"; - } - } else { - if (abs[abs.length() - 1] == '/') { - abs.erase(abs.length() - 1, abs.length() - 1); - } - this->relpath = abs; - if (fileExists(webroot + abs + ".php")) { - this->filepath = webroot + abs + ".php"; - } else if (fileExists(webroot + abs + ".html")) { - this->filepath = webroot + abs + ".html"; - } - } + if (isDirectory(webroot + abs)) { + if (abs[abs.length() - 1] != '/') { + abs += "/"; + } + this->relpath = abs; + abs += "index"; + if (fileExists(webroot + abs + ".php")) { + this->filepath = webroot + abs + ".php"; + } else if (fileExists(webroot + abs + ".html")) { + this->filepath = webroot + abs + ".html"; + } + } else { + if (abs[abs.length() - 1] == '/') { + abs.erase(abs.length() - 1, abs.length() - 1); + } + this->relpath = abs; + if (fileExists(webroot + abs + ".php")) { + this->filepath = webroot + abs + ".php"; + } else if (fileExists(webroot + abs + ".html")) { + this->filepath = webroot + abs + ".html"; + } + } - if (isStatic() && !info.empty()) { - if (relpath[relpath.length() - 1] == '/') { - relpath.erase(relpath.length() - 1); - } - newpath = relpath + info; - filepath = ""; - } else if (relpath != reqpath) { - if (!info.empty() && relpath[relpath.length() - 1] == '/') { - info.erase(0,1); - } - newpath = relpath + info; - } else { - newpath = ""; - } + if (isStatic() && !info.empty()) { + if (relpath[relpath.length() - 1] == '/') { + relpath.erase(relpath.length() - 1); + } + newpath = relpath + info; + filepath = ""; + } else if (relpath != reqpath) { + if (!info.empty() && relpath[relpath.length() - 1] == '/') { + info.erase(0,1); + } + newpath = relpath + info; + } else { + newpath = ""; + } } string URI::getWebRoot() { - return webroot; + return webroot; } string URI::getRelativePath() { - return relpath; + return relpath; } string URI::getAbsolutePath() { - return webroot + relpath; + return webroot + relpath; } string URI::getFilePath() { - return filepath; + return filepath; } string URI::getRelativeFilePath() { - string str = getFilePath(); - long len = getWebRoot().length(); - return str.substr(len, str.length() - len); + string str = getFilePath(); + long len = getWebRoot().length(); + return str.substr(len, str.length() - len); } string URI::getNewPath() { - if (isStatic()) { - if (hasQuery()) { - return getRelativePath(); - } - } - if (!newpath.empty() && newpath != reqpath) { - return url_encode(newpath) + (queryinit? "?" + query : ""); - } else { - return ""; - } + if (isStatic()) { + if (hasQuery()) { + return getRelativePath(); + } + } + if (!newpath.empty() && newpath != reqpath) { + return url_encode(newpath) + (queryinit? "?" + query : ""); + } else { + return ""; + } } FILE *URI::openFile() { - return fopen64(getFilePath().c_str(), "rb"); + return fopen64(getFilePath().c_str(), "rb"); } string URI::getFilePathInfo() { - return info; //getAbsolutePath().erase(getFilePath().length(), getAbsolutePath().length()); + return info; //getAbsolutePath().erase(getFilePath().length(), getAbsolutePath().length()); } string URI::getFileType() { - return getMimeType(getFilePath()); + return getMimeType(getFilePath()); } bool URI::isStatic() { - return getExtension(filepath) != "php"; + return getExtension(filepath) != "php"; } string URI::getQuery() { - return query; + return query; } bool URI::hasQuery() { - return queryinit; + return queryinit; } diff --git a/src/URI.h b/src/URI.h index 9398437..9a97be4 100644 --- a/src/URI.h +++ b/src/URI.h @@ -8,41 +8,41 @@ using namespace std; class URI { private: - string webroot; - string reqpath; - string relpath; - string query; - string info; - string filepath; - string newpath; - bool queryinit; + string webroot; + string reqpath; + string relpath; + string query; + string info; + string filepath; + string newpath; + bool queryinit; public: - URI(string webroot, string reqpath); + URI(string webroot, string reqpath); - string getWebRoot(); + string getWebRoot(); - string getRelativePath(); + string getRelativePath(); - string getAbsolutePath(); + string getAbsolutePath(); - string getFilePath(); + string getFilePath(); - string getRelativeFilePath(); + string getRelativeFilePath(); - string getNewPath(); + string getNewPath(); - FILE *openFile(); + FILE *openFile(); - string getFilePathInfo(); + string getFilePathInfo(); - string getFileType(); + string getFileType(); - bool isStatic(); + bool isStatic(); - string getQuery(); + string getQuery(); - bool hasQuery(); + bool hasQuery(); }; diff --git a/src/client.cpp b/src/client.cpp index 7328436..04a7d69 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -58,20 +58,20 @@ void log_error_to_file(const char *prefix, const string &str, string host) { * @param str The string to be written */ void log(const char *prefix, const string &str) { - printf("%s%s\r\n", prefix, str.c_str()); - flush(cout); + printf("%s%s\r\n", prefix, str.c_str()); + flush(cout); } void log_error(const char *prefix, const string &str) { - log(prefix, "\x1B[1;31m" + str + "\x1B[0m"); + log(prefix, "\x1B[1;31m" + str + "\x1B[0m"); } void php_error_handler(const char *prefix, FILE *stderr) { - string line; - while (!(line = read_line(stderr)).empty()) { - log_error(prefix, line); - } - fclose(stderr); + string line; + while (!(line = read_line(stderr)).empty()) { + log_error(prefix, line); + } + fclose(stderr); } IpAddressInfo get_ip_address_info(Address* addr) { @@ -101,78 +101,78 @@ IpAddressInfo get_ip_address_info(Address* addr) { } string getETag(string filename) { - ifstream etags = ifstream("/var/necronda/ETags"); + ifstream etags = ifstream("/var/necronda/ETags"); - ifstream a = ifstream(); - string line; - int index = 0; - int i = 0; - string timestamp = getTimestamp(filename); - long size = getFileSize(filename); - while (getline(etags, line)) { - i++; - if (line == filename) { - index = i; - break; - } - long p1 = line.find(':'); - if (p1 == string::npos) continue; - long p2 = line.find(':', (unsigned) p1 + 1); - if (p2 == string::npos) continue; - long p3 = line.find(':', (unsigned) p2 + 1); - if (p3 == string::npos) continue; - string FILENAME = line.substr(0, (unsigned) p1); - string HASH = line.substr((unsigned) p1 + 1, (unsigned) (p2 - p1)); - string TIMESTAMP = line.substr((unsigned) p2 + 1, (unsigned) (p3 - p2)); - long SIZE = strtol(line.substr((unsigned) p3 + 1, line.length() - p3).c_str(), nullptr, 10); - if (FILENAME == filename) { - index = i; - if (timestamp != TIMESTAMP || size != SIZE) { - break; - } else { - etags.close(); - return HASH; - } - } - } - etags.close(); + ifstream a = ifstream(); + string line; + int index = 0; + int i = 0; + string timestamp = getTimestamp(filename); + long size = getFileSize(filename); + while (getline(etags, line)) { + i++; + if (line == filename) { + index = i; + break; + } + long p1 = line.find(':'); + if (p1 == string::npos) continue; + long p2 = line.find(':', (unsigned) p1 + 1); + if (p2 == string::npos) continue; + long p3 = line.find(':', (unsigned) p2 + 1); + if (p3 == string::npos) continue; + string FILENAME = line.substr(0, (unsigned) p1); + string HASH = line.substr((unsigned) p1 + 1, (unsigned) (p2 - p1)); + string TIMESTAMP = line.substr((unsigned) p2 + 1, (unsigned) (p3 - p2)); + long SIZE = strtol(line.substr((unsigned) p3 + 1, line.length() - p3).c_str(), nullptr, 10); + if (FILENAME == filename) { + index = i; + if (timestamp != TIMESTAMP || size != SIZE) { + break; + } else { + etags.close(); + return HASH; + } + } + } + etags.close(); - MD5_CTX mdContext; - MD5_Init(&mdContext); - size_t bytes; - char buffer[4096]; - FILE *file = fopen(filename.c_str(), "rb"); - if (file == nullptr) { - throw (char *) "Invalid file"; - } - while ((bytes = fread(buffer, 1, 4096, file)) != 0) { - MD5_Update(&mdContext, buffer, bytes); - } - fclose(file); - unsigned char md[16]; - MD5_Final(md, &mdContext); - char md5buff[32]; - for (int i = 0; i < 16; i++) { - sprintf(md5buff + i * 2, "%02x", md[i]); - } - string md5 = string(md5buff); + MD5_CTX mdContext; + MD5_Init(&mdContext); + size_t bytes; + char buffer[4096]; + FILE *file = fopen(filename.c_str(), "rb"); + if (file == nullptr) { + throw (char *) "Invalid file"; + } + while ((bytes = fread(buffer, 1, 4096, file)) != 0) { + MD5_Update(&mdContext, buffer, bytes); + } + fclose(file); + unsigned char md[16]; + MD5_Final(md, &mdContext); + char md5buff[32]; + for (int i = 0; i < 16; i++) { + sprintf(md5buff + i * 2, "%02x", md[i]); + } + string md5 = string(md5buff); - if (index == 0) { - char buff[256]; - sprintf(buff, "%s:%s:%s:%ld\n", filename.c_str(), md5.c_str(), timestamp.c_str(), size); - FILE *f = fopen("/var/necronda/ETags", "a"); - if (f == nullptr) { - throw (char *) strerror(errno); - } - fseek(f, 0, SEEK_END); - fwrite(buff, 1, strlen(buff), f); - fflush(f); - fclose(f); - } else { + if (index == 0) { + char buff[256]; + sprintf(buff, "%s:%s:%s:%ld\n", filename.c_str(), md5.c_str(), timestamp.c_str(), size); + FILE *f = fopen("/var/necronda/ETags", "a"); + if (f == nullptr) { + throw (char *) strerror(errno); + } + fseek(f, 0, SEEK_END); + fwrite(buff, 1, strlen(buff), f); + fflush(f); + fclose(f); + } else { - } + } - return md5; + return md5; } #include @@ -181,18 +181,18 @@ string getETag(string filename) { long getPosition(std::string str, char c, int occurence) { - int tempOccur = 0; - int num = 0; - for (auto it : str) { - num++; - if (it == c) { - if (++tempOccur == occurence) { - return num; - } - } - } + int tempOccur = 0; + int num = 0; + for (auto it : str) { + num++; + if (it == c) { + if (++tempOccur == occurence) { + return num; + } + } + } - return -1; + return -1; } /** @@ -204,314 +204,314 @@ long getPosition(std::string str, char c, int occurence) { * @return Should the server wait for another header? */ bool connection_handler(const char *preprefix, const char *col1, const char *col2, Socket *socket, long id, long num, IpAddressInfo *info) { - bool error = false; - char buffer[1024]; - char *prefix = (char *) preprefix; - try { - HttpConnection req(socket); - try { - if (req.isExistingField("Connection") && req.getField("Connection") == "keep-alive") { - req.setField("Connection", "keep-alive"); - req.setField("Keep-Alive", "timeout=60, max=100"); - } else { - req.setField("Connection", "close"); - error = true; - } + bool error = false; + char buffer[1024]; + char *prefix = (char *) preprefix; + try { + HttpConnection req(socket); + try { + if (req.isExistingField("Connection") && req.getField("Connection") == "keep-alive") { + req.setField("Connection", "keep-alive"); + req.setField("Keep-Alive", "timeout=60, max=100"); + } else { + req.setField("Connection", "close"); + error = true; + } - string host = ""; + string host = ""; - if (!req.isExistingField("Host")) { - req.respond(400); - } else { - host = req.getField("Host"); - long pos = host.find(':'); - if (pos != string::npos) { - host.erase(pos, host.length() - pos); - } + if (!req.isExistingField("Host")) { + req.respond(400); + } else { + host = req.getField("Host"); + long pos = host.find(':'); + if (pos != string::npos) { + host.erase(pos, host.length() - pos); + } - /*FILE *name = popen(("dig @8.8.8.8 +time=1 -x " + socket->getPeerAddress()->toString() + - " | grep -oP \"^[^;].*\\t\\K([^ ]*)\\w\"").c_str(), "r"); - char hostbuffer[1024]; - memset(hostbuffer, 0, 1024); - size_t size = fread(hostbuffer, 1, 1024, name); - hostbuffer[size - 1] = 0; // remove \n - if (size <= 1) { - sprintf(hostbuffer, "%s", socket->getPeerAddress()->toString().c_str()); - }*/ + /*FILE *name = popen(("dig @8.8.8.8 +time=1 -x " + socket->getPeerAddress()->toString() + + " | grep -oP \"^[^;].*\\t\\K([^ ]*)\\w\"").c_str(), "r"); + char hostbuffer[1024]; + memset(hostbuffer, 0, 1024); + size_t size = fread(hostbuffer, 1, 1024, name); + hostbuffer[size - 1] = 0; // remove \n + if (size <= 1) { + sprintf(hostbuffer, "%s", socket->getPeerAddress()->toString().c_str()); + }*/ - sprintf(buffer, "[\x1B[1m%s\x1B[0m][%i]%s[%s][%i]%s ", host.c_str(), socket->getSocketPort(), col1, - info->host.c_str(), socket->getPeerPort(), col2); - prefix = buffer; + sprintf(buffer, "[\x1B[1m%s\x1B[0m][%i]%s[%s][%i]%s ", host.c_str(), socket->getSocketPort(), col1, + info->host.c_str(), socket->getPeerPort(), col2); + prefix = buffer; - log(prefix, "\x1B[1m" + req.getMethod() + " " + req.getPath() + "\x1B[0m"); - log_to_file(prefix, "\x1B[1m" + req.getMethod() + " " + req.getPath() + "\x1B[0m", host); + log(prefix, "\x1B[1m" + req.getMethod() + " " + req.getPath() + "\x1B[0m"); + log_to_file(prefix, "\x1B[1m" + req.getMethod() + " " + req.getPath() + "\x1B[0m", host); - bool noRedirect = req.getPath().find("/.well-known/") == 0 || (req.getPath().find("/files/") == 0); + bool noRedirect = req.getPath().find("/.well-known/") == 0 || (req.getPath().find("/files/") == 0); - bool redir = true; - if (!noRedirect) { - if (getWebRoot(host).empty()) { - req.redirect(303, "https://www.necronda.net" + req.getPath()); - } else if (socket->getSocketPort() != 443) { - req.redirect(302, "https://" + host + req.getPath()); - } else { - redir = false; - } - } else { - redir = false; - } + bool redir = true; + if (!noRedirect) { + if (getWebRoot(host).empty()) { + req.redirect(303, "https://www.necronda.net" + req.getPath()); + } else if (socket->getSocketPort() != 443) { + req.redirect(302, "https://" + host + req.getPath()); + } else { + redir = false; + } + } else { + redir = false; + } - URI path = URI(getWebRoot(host), req.getPath()); - pid_t childpid = 0; + URI path = URI(getWebRoot(host), req.getPath()); + pid_t childpid = 0; - if (redir) { + if (redir) { - } else if (!path.getNewPath().empty() && req.getMethod() != "POST") { - req.redirect(303, path.getNewPath()); - } else { - FILE *file = path.openFile(); - if (file == nullptr) { - req.setField("Cache-Control", "public, max-age=60"); - req.respond(404); - } else { - string type = path.getFileType(); + } else if (!path.getNewPath().empty() && req.getMethod() != "POST") { + req.redirect(303, path.getNewPath()); + } else { + FILE *file = path.openFile(); + if (file == nullptr) { + req.setField("Cache-Control", "public, max-age=60"); + req.respond(404); + } else { + string type = path.getFileType(); - if (type.find("inode/") == 0) { - req.respond(403); - } else if (path.getRelativeFilePath().find("/.") != string::npos && !noRedirect) { - req.respond(403); - } else { - req.setField("Content-Type", type); - req.setField("Last-Modified", getHttpDate(path.getFilePath())); + if (type.find("inode/") == 0) { + req.respond(403); + } else if (path.getRelativeFilePath().find("/.") != string::npos && !noRedirect) { + req.respond(403); + } else { + req.setField("Content-Type", type); + req.setField("Last-Modified", getHttpDate(path.getFilePath())); - bool invalidMethod = false; - bool etag = false; + bool invalidMethod = false; + bool etag = false; - if (path.isStatic()) { - string hash = getETag(path.getFilePath()); - req.setField("ETag", hash); - req.setField("Accept-Ranges", "bytes"); - if (type.find("text/") == 0) { - req.setField("Cache-Control", "public, max-age=3600"); - } else { - req.setField("Cache-Control", "public, max-age=86400"); - } - req.setField("Allow", "GET"); - if (req.getMethod() != "GET") { - invalidMethod = true; - } - if (req.isExistingField("If-None-Match") && req.getField("If-None-Match") == hash) { - etag = true; - } - } else { - req.setField("Accept-Ranges", "none"); - req.setField("Cache-Control", "private, no-cache"); - req.setField("Allow", "GET, POST, PUT"); - if (req.getMethod() != "GET" && req.getMethod() != "POST" && req.getMethod() != "PUT") { - invalidMethod = true; - } - } + if (path.isStatic()) { + string hash = getETag(path.getFilePath()); + req.setField("ETag", hash); + req.setField("Accept-Ranges", "bytes"); + if (type.find("text/") == 0) { + req.setField("Cache-Control", "public, max-age=3600"); + } else { + req.setField("Cache-Control", "public, max-age=86400"); + } + req.setField("Allow", "GET"); + if (req.getMethod() != "GET") { + invalidMethod = true; + } + if (req.isExistingField("If-None-Match") && req.getField("If-None-Match") == hash) { + etag = true; + } + } else { + req.setField("Accept-Ranges", "none"); + req.setField("Cache-Control", "private, no-cache"); + req.setField("Allow", "GET, POST, PUT"); + if (req.getMethod() != "GET" && req.getMethod() != "POST" && req.getMethod() != "PUT") { + invalidMethod = true; + } + } - if (invalidMethod) { - req.respond(405); - } else if (etag) { - req.respond(304); - } else { - int statuscode = 0; - if (!path.isStatic()) { - string cmd = (string) "env -i" + - " REDIRECT_STATUS=" + cli_encode("CGI") + - " DOCUMENT_ROOT=" + cli_encode(getWebRoot(host)) + - " " + req.cgiExport() + - (req.isExistingField("Content-Length") ? " CONTENT_LENGTH=" + - cli_encode(req.getField( - "Content-Length")) - : "") + - (req.isExistingField("Content-Type") ? " CONTENT_TYPE=" + cli_encode( - req.getField("Content-Type")) : "") + - ((socket->isSecured()) ? " HTTPS=on" : "") + - " PATH_INFO=" + cli_encode(path.getFilePathInfo()) + - " PATH_TRANSLATED=" + cli_encode(path.getAbsolutePath()) + - " QUERY_STRING=" + cli_encode(path.getQuery()) + - " REMOTE_ADDR=" + cli_encode(socket->getPeerAddress()->toString()) + - " REMOTE_HOST=" + cli_encode(info->host) + - " REMOTE_PORT=" + cli_encode(to_string(socket->getPeerPort())) + - " REQUEST_METHOD=" + cli_encode(req.getMethod()) + - " REQUEST_URI=" + cli_encode(req.getPath()) + - " SCRIPT_FILENAME=" + cli_encode(path.getFilePath()) + - " SCRIPT_NAME=" + cli_encode(path.getRelativePath()) + - " SERVER_ADMIN=" + cli_encode("lorenz.stechauner@gmail.com") + - " SERVER_NAME=" + cli_encode(host) + - " SERVER_PORT=" + cli_encode(to_string(socket->getSocketPort())) + - " SERVER_SOFTWARE=" + cli_encode("Necronda 3.0") + - " SERVER_PROTOCOL=" + cli_encode("HTTP/1.1") + - " GATEWAY_INTERFACE=" + cli_encode("CGI/1.1") + - " /usr/bin/php-cgi"; + if (invalidMethod) { + req.respond(405); + } else if (etag) { + req.respond(304); + } else { + int statuscode = 0; + if (!path.isStatic()) { + string cmd = (string) "env -i" + + " REDIRECT_STATUS=" + cli_encode("CGI") + + " DOCUMENT_ROOT=" + cli_encode(getWebRoot(host)) + + " " + req.cgiExport() + + (req.isExistingField("Content-Length") ? " CONTENT_LENGTH=" + + cli_encode(req.getField( + "Content-Length")) + : "") + + (req.isExistingField("Content-Type") ? " CONTENT_TYPE=" + cli_encode( + req.getField("Content-Type")) : "") + + ((socket->isSecured()) ? " HTTPS=on" : "") + + " PATH_INFO=" + cli_encode(path.getFilePathInfo()) + + " PATH_TRANSLATED=" + cli_encode(path.getAbsolutePath()) + + " QUERY_STRING=" + cli_encode(path.getQuery()) + + " REMOTE_ADDR=" + cli_encode(socket->getPeerAddress()->toString()) + + " REMOTE_HOST=" + cli_encode(info->host) + + " REMOTE_PORT=" + cli_encode(to_string(socket->getPeerPort())) + + " REQUEST_METHOD=" + cli_encode(req.getMethod()) + + " REQUEST_URI=" + cli_encode(req.getPath()) + + " SCRIPT_FILENAME=" + cli_encode(path.getFilePath()) + + " SCRIPT_NAME=" + cli_encode(path.getRelativePath()) + + " SERVER_ADMIN=" + cli_encode("lorenz.stechauner@gmail.com") + + " SERVER_NAME=" + cli_encode(host) + + " SERVER_PORT=" + cli_encode(to_string(socket->getSocketPort())) + + " SERVER_SOFTWARE=" + cli_encode("Necronda 3.0") + + " SERVER_PROTOCOL=" + cli_encode("HTTP/1.1") + + " GATEWAY_INTERFACE=" + cli_encode("CGI/1.1") + + " /usr/bin/php-cgi"; - stds pipes = procopen(cmd.c_str()); - childpid = pipes.pid; + stds pipes = procopen(cmd.c_str()); + childpid = pipes.pid; - long len = req.isExistingField("Content-Length") ? strtol(req.getField("Content-Length").c_str(), nullptr, 10) : (req.getMethod() == "POST" || req.getMethod() == "PUT")?-1:0; - socket->receive(pipes.stdin, len); - fclose(pipes.stdin); + long len = req.isExistingField("Content-Length") ? strtol(req.getField("Content-Length").c_str(), nullptr, 10) : (req.getMethod() == "POST" || req.getMethod() == "PUT")?-1:0; + socket->receive(pipes.stdin, len); + fclose(pipes.stdin); - thread *t = new thread(php_error_handler, prefix, pipes.stderr); + thread *t = new thread(php_error_handler, prefix, pipes.stderr); - string line; - while (!(line = read_line(pipes.stdout)).empty()) { - long pos = line.find(':'); - string index = line.substr(0, pos); - string data = line.substr(pos + 1, line.length() - pos); + string line; + while (!(line = read_line(pipes.stdout)).empty()) { + long pos = line.find(':'); + string index = line.substr(0, pos); + string data = line.substr(pos + 1, line.length() - pos); - while (index[0] == ' ') index.erase(index.begin() + 0); - while (index[index.length() - 1] == ' ') index.erase(index.end() - 1); - while (data[0] == ' ') data.erase(data.begin() + 0); - while (data[data.length() - 1] == ' ') data.erase(data.end() - 1); + while (index[0] == ' ') index.erase(index.begin() + 0); + while (index[index.length() - 1] == ' ') index.erase(index.end() - 1); + while (data[0] == ' ') data.erase(data.begin() + 0); + while (data[data.length() - 1] == ' ') data.erase(data.end() - 1); - if (index == "Status") { - statuscode = (int) strtol(data.substr(0, 3).c_str(), nullptr, 10); - } else { - if (index == "Location" && statuscode == 0) { - statuscode = 303; - } - req.setField(index, data); - } - } + if (index == "Status") { + statuscode = (int) strtol(data.substr(0, 3).c_str(), nullptr, 10); + } else { + if (index == "Location" && statuscode == 0) { + statuscode = 303; + } + req.setField(index, data); + } + } - fclose(file); - int c = fgetc(pipes.stdout); - if (c == -1) { - // No Data -> Error - req.respond((statuscode == 0) ? 500 : statuscode); - statuscode = -1; - } else { - ungetc(c, pipes.stdout); - } - file = pipes.stdout; - } + fclose(file); + int c = fgetc(pipes.stdout); + if (c == -1) { + // No Data -> Error + req.respond((statuscode == 0) ? 500 : statuscode); + statuscode = -1; + } else { + ungetc(c, pipes.stdout); + } + file = pipes.stdout; + } - if (statuscode != -1) { - statuscode = (statuscode == 0) ? 200 : statuscode; + if (statuscode != -1) { + statuscode = (statuscode == 0) ? 200 : statuscode; - bool compress = /*path.isStatic() &&*/ type.find("text/") == 0 && - req.isExistingField("Accept-Encoding") && - req.getField("Accept-Encoding").find( - "deflate") != string::npos; + bool compress = /*path.isStatic() &&*/ type.find("text/") == 0 && + req.isExistingField("Accept-Encoding") && + req.getField("Accept-Encoding").find( + "deflate") != string::npos; - if (compress) { - req.setField("Accept-Ranges", "none"); - } + if (compress) { + req.setField("Accept-Ranges", "none"); + } - if (compress && req.isExistingField("Range")) { - req.respond(416); - } else 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, (unsigned long) (p - 6)); - string part2 = range.substr((unsigned long) (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(statuscode, file, compress); - } - } - } - } - fclose(file); - if (childpid > 0) { - waitpid(childpid, nullptr, 0); - } - } - } - } - HttpStatusCode status = req.getStatusCode(); - int code = status.code; - string color = ""; - string comment = ""; - if ((code >= 200 && code < 300) || code == 304) { - color = "\x1B[1;32m"; // Success (Cached): Green - } else if (code >= 100 && code < 200) { - color = "\x1B[1;93m"; // Continue: Yellow - } else if (code >= 300 && code < 400) { - color = "\x1B[1;93m"; // Redirect: Yellow - comment = " -> " + - (req.isExistingResponseField("Location") ? req.getResponseField("Location") : ""); - } else if (code >= 400 && code < 500) { - color = "\x1B[1;31m"; // Client Error: Red - //comment = " -> " + req.getPath(); - } else if (code >= 500 & code < 600) { - color = "\x1B[1;31m"; // Server Error: Red - //comment = " -> " + req.getPath(); - } - string msg = color + to_string(status.code) + " " + status.message + comment + " (" + formatTime(req.getDuration()) + ")\x1B[0m"; - log(prefix, msg); - if (!host.empty()) { + if (compress && req.isExistingField("Range")) { + req.respond(416); + } else 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, (unsigned long) (p - 6)); + string part2 = range.substr((unsigned long) (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(statuscode, file, compress); + } + } + } + } + fclose(file); + if (childpid > 0) { + waitpid(childpid, nullptr, 0); + } + } + } + } + HttpStatusCode status = req.getStatusCode(); + int code = status.code; + string color = ""; + string comment = ""; + if ((code >= 200 && code < 300) || code == 304) { + color = "\x1B[1;32m"; // Success (Cached): Green + } else if (code >= 100 && code < 200) { + color = "\x1B[1;93m"; // Continue: Yellow + } else if (code >= 300 && code < 400) { + color = "\x1B[1;93m"; // Redirect: Yellow + comment = " -> " + + (req.isExistingResponseField("Location") ? req.getResponseField("Location") : ""); + } else if (code >= 400 && code < 500) { + color = "\x1B[1;31m"; // Client Error: Red + //comment = " -> " + req.getPath(); + } else if (code >= 500 & code < 600) { + color = "\x1B[1;31m"; // Server Error: Red + //comment = " -> " + req.getPath(); + } + string msg = color + to_string(status.code) + " " + status.message + comment + " (" + formatTime(req.getDuration()) + ")\x1B[0m"; + log(prefix, msg); + if (!host.empty()) { log_to_file(prefix, msg, host); } - } catch (char *msg) { - HttpStatusCode status = req.getStatusCode(); - log(prefix, to_string(status.code) + " " + status.message + " (" + formatTime(req.getDuration()) + ")"); - try { - if (strncmp(msg, "timeout", strlen(msg)) == 0) { - log(prefix, "Timeout!"); - req.setField("Connection", "close"); - req.respond(408); - error = true; - } else if (strncmp(msg, "Invalid path", strlen(msg)) == 0) { - log(prefix, "Timeout!"); - req.setField("Connection", "close"); - req.respond(400); - } else { - log(prefix, (string) "Unable to receive from socket: " + msg); - error = true; - } - } catch (char *msg2) { + } catch (char *msg) { + HttpStatusCode status = req.getStatusCode(); + log(prefix, to_string(status.code) + " " + status.message + " (" + formatTime(req.getDuration()) + ")"); + try { + if (strncmp(msg, "timeout", strlen(msg)) == 0) { + log(prefix, "Timeout!"); + req.setField("Connection", "close"); + req.respond(408); + error = true; + } else if (strncmp(msg, "Invalid path", strlen(msg)) == 0) { + log(prefix, "Timeout!"); + req.setField("Connection", "close"); + req.respond(400); + } else { + log(prefix, (string) "Unable to receive from socket: " + msg); + error = true; + } + } catch (char *msg2) { - } - } - } catch (char *msg) { - try { - if (msg == "Malformed header") { - log(prefix, "Unable to parse header: Malformed header"); - socket->send("HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n"); - error = true; - } else if (msg == "timeout") { - log(prefix, "Timeout!"); - socket->send("HTTP/1.1 408 Request Timeout\r\nConnection: close\r\n\r\n"); - error = true; - } else { - log(prefix, (string) "Unable to receive from socket: " + msg); - error = true; - } - } catch (char *msg2) { + } + } + } catch (char *msg) { + try { + if (msg == "Malformed header") { + log(prefix, "Unable to parse header: Malformed header"); + socket->send("HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n"); + error = true; + } else if (msg == "timeout") { + log(prefix, "Timeout!"); + socket->send("HTTP/1.1 408 Request Timeout\r\nConnection: close\r\n\r\n"); + error = true; + } else { + log(prefix, (string) "Unable to receive from socket: " + msg); + error = true; + } + } catch (char *msg2) { - } - } - return !error; + } + } + return !error; } /** @@ -520,70 +520,70 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col * @param id The client ID */ void client_handler(Socket *socket, long id, bool ssl) { - const char *prefix; - char const *col1; - char const *col2 = "\x1B[0m"; + const char *prefix; + char const *col1; + char const *col2 = "\x1B[0m"; IpAddressInfo info = get_ip_address_info(socket->getPeerAddress()); - { - auto group = (int) (id % 6); - if (group == 0) { - col1 = "\x1B[0;31m"; // Red - } else if (group == 1) { - col1 = "\x1B[0;32m"; // Green - } else if (group == 2) { - col1 = "\x1B[0;34m"; // Blue - } else if (group == 3) { - col1 = "\x1B[0;33m"; // Yellow - } else if (group == 4) { - col1 = "\x1B[0;35m"; // Magenta - } else { - col1 = "\x1B[0;36m"; // Cyan - } + { + auto group = (int) (id % 6); + if (group == 0) { + col1 = "\x1B[0;31m"; // Red + } else if (group == 1) { + col1 = "\x1B[0;32m"; // Green + } else if (group == 2) { + col1 = "\x1B[0;34m"; // Blue + } else if (group == 3) { + col1 = "\x1B[0;33m"; // Yellow + } else if (group == 4) { + col1 = "\x1B[0;35m"; // Magenta + } else { + col1 = "\x1B[0;36m"; // Cyan + } - string *a = new string("[" + socket->getSocketAddress()->toString() + "][" + - to_string(socket->getSocketPort()) + "]" + col1 + - "[" + info.host + "][" + to_string(socket->getPeerPort()) + - "]" + col2 + " "); - prefix = a->c_str(); - } + string *a = new string("[" + socket->getSocketAddress()->toString() + "][" + + to_string(socket->getSocketPort()) + "]" + col1 + + "[" + info.host + "][" + to_string(socket->getPeerPort()) + + "]" + col2 + " "); + prefix = a->c_str(); + } - log(prefix, "Connection established"); + log(prefix, "Connection established"); log(prefix, string("Host: ") + info.host + " (" + socket->getPeerAddress()->toString() + ")"); log(prefix, string("Location: ") + info.cc + "/" + info.country + ", " + info.prov + "/" + info.provname + ", " + info.city); log(prefix, string("Local Date: ") + info.localdate + " (" + info.timezone + ")"); - bool err = false; - try { - socket->setReceiveTimeout(60000); - socket->setSendTimeout(60000); - } catch (char *msg) { - log(prefix, (string) "Unable to set timeout on socket: " + msg); - err = true; - } + bool err = false; + try { + socket->setReceiveTimeout(60000); + socket->setSendTimeout(60000); + } catch (char *msg) { + log(prefix, (string) "Unable to set timeout on socket: " + msg); + err = true; + } - try { - if (ssl) { - //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"); - socket->sslHandshake("/cert/necronda.net/privkey.pem", - "/cert/necronda.net/fullchain.pem"); - } - } catch (char *msg) { - log(prefix, (string) "Unable to perform handshake: " + msg); - err = true; - } + try { + if (ssl) { + //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"); + socket->sslHandshake("/cert/necronda.net/privkey.pem", + "/cert/necronda.net/fullchain.pem"); + } + } catch (char *msg) { + log(prefix, (string) "Unable to perform handshake: " + msg); + err = true; + } - long reqnum = 0; - if (!err) { - while (connection_handler(prefix, col1, col2, socket, id, ++reqnum, &info)); - reqnum--; - } + long reqnum = 0; + if (!err) { + while (connection_handler(prefix, col1, col2, socket, id, ++reqnum, &info)); + reqnum--; + } - log(prefix, - "Connection terminated (#:" + to_string(reqnum) + ", R: " + formatSize(socket->getBytesReceived()) + ", S: " + - formatSize(socket->getBytesSent()) + ", T: " + formatTime(socket->getDuration()) + ")"); - socket->close(); + log(prefix, + "Connection terminated (#:" + to_string(reqnum) + ", R: " + formatSize(socket->getBytesReceived()) + ", S: " + + formatSize(socket->getBytesSent()) + ", T: " + formatTime(socket->getDuration()) + ")"); + socket->close(); } diff --git a/src/necronda-server.cpp b/src/necronda-server.cpp index b14521f..ac2a6c3 100644 --- a/src/necronda-server.cpp +++ b/src/necronda-server.cpp @@ -22,29 +22,29 @@ const char* webroot = "/srv/necronda/"; string getMimeType(string path) { - unsigned long pos = path.find_last_of('.'); - string ext; - if (pos != string::npos) { - ext = path.substr(pos + 1, path.length() - pos); - } + unsigned long pos = path.find_last_of('.'); + string ext; + if (pos != string::npos) { + ext = path.substr(pos + 1, path.length() - pos); + } - magic_t magic = magic_open(MAGIC_MIME_TYPE); - magic_load(magic, "/usr/share/misc/magic.mgc"); - string type = magic_file(magic, path.c_str()); - magic_setflags(magic, MAGIC_MIME_ENCODING); - string charset = magic_file(magic, path.c_str()); + magic_t magic = magic_open(MAGIC_MIME_TYPE); + magic_load(magic, "/usr/share/misc/magic.mgc"); + string type = magic_file(magic, path.c_str()); + magic_setflags(magic, MAGIC_MIME_ENCODING); + string charset = magic_file(magic, path.c_str()); - if (type == "text/plain") { - if (ext == "css") { - type = "text/css"; - } else if (ext == "js") { - type = "text/javascript"; - } - } + if (type == "text/plain") { + if (ext == "css") { + type = "text/css"; + } else if (ext == "js") { + type = "text/javascript"; + } + } - magic_close(magic); + magic_close(magic); - return type + "; charset=" + charset; + return type + "; charset=" + charset; } /** @@ -53,22 +53,22 @@ string getMimeType(string path) { */ std::string getTimestamp(string path) { - struct stat attrib; - stat(path.c_str(), &attrib); - return getTimestamp(attrib.st_ctime); + struct stat attrib; + stat(path.c_str(), &attrib); + return getTimestamp(attrib.st_ctime); } std::string getTimestamp(time_t time) { - char buffer[64]; - struct tm *timeinfo = gmtime(&time); - strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", timeinfo); - return string(buffer); + char buffer[64]; + struct tm *timeinfo = gmtime(&time); + strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", timeinfo); + return string(buffer); } long getFileSize(string filename) { - struct stat stat_buf; - int rc = stat(filename.c_str(), &stat_buf); - return rc == 0 ? stat_buf.st_size : -1; + struct stat stat_buf; + int rc = stat(filename.c_str(), &stat_buf); + return rc == 0 ? stat_buf.st_size : -1; } @@ -78,104 +78,104 @@ long getFileSize(string filename) { * @return A formatted time string */ std::string formatTime(long micros) { - char buffer[64]; - if (micros < 1000) { - sprintf(buffer, "%.3f ms", micros / 1000.0); - } else if (micros < 10000) { - sprintf(buffer, "%.2f ms", micros / 1000.0); - } else if (micros < 100000) { - sprintf(buffer, "%.1f ms", micros / 1000.0); - } else if (micros < 1000000) { - sprintf(buffer, "%.0f ms", micros / 1000.0); - } else { - sprintf(buffer, "%.1f s", micros / 1000000.0); - } - return std::string(buffer); + char buffer[64]; + if (micros < 1000) { + sprintf(buffer, "%.3f ms", micros / 1000.0); + } else if (micros < 10000) { + sprintf(buffer, "%.2f ms", micros / 1000.0); + } else if (micros < 100000) { + sprintf(buffer, "%.1f ms", micros / 1000.0); + } else if (micros < 1000000) { + sprintf(buffer, "%.0f ms", micros / 1000.0); + } else { + sprintf(buffer, "%.1f s", micros / 1000000.0); + } + return std::string(buffer); } std::string formatSize(unsigned long bytes) { - char buffer[64]; - if (bytes > 0x10000000000) { - sprintf(buffer, "%.1f TiB", (double) bytes / 0x10000000000); - } else if (bytes > 0x40000000) { - sprintf(buffer, "%.1f GiB", (double) bytes / 0x40000000); - } else if (bytes > 0x100000) { - sprintf(buffer, "%.1f MiB", (double) bytes / 0x100000); - } else if (bytes > 0x400) { - sprintf(buffer, "%.1f KiB", (double) bytes / 0x400); - } else { - sprintf(buffer, "%ld B", bytes); - } - return std::string(buffer); + char buffer[64]; + if (bytes > 0x10000000000) { + sprintf(buffer, "%.1f TiB", (double) bytes / 0x10000000000); + } else if (bytes > 0x40000000) { + sprintf(buffer, "%.1f GiB", (double) bytes / 0x40000000); + } else if (bytes > 0x100000) { + sprintf(buffer, "%.1f MiB", (double) bytes / 0x100000); + } else if (bytes > 0x400) { + sprintf(buffer, "%.1f KiB", (double) bytes / 0x400); + } else { + sprintf(buffer, "%ld B", bytes); + } + return std::string(buffer); } string url_decode(string url) { - long pos = 0; - while ((pos = url.find('+', pos + 1)) != string::npos) { - url.replace(pos, 1, 1, ' '); - } - pos = 0; - while ((pos = url.find('%', pos + 1)) != string::npos) { - const char *num = url.substr(pos + 1, 2).c_str(); - auto c = (char) strtol(num, nullptr, 16); - url.erase(pos, 3); - url.insert(pos, 1, c); - } + long pos = 0; + while ((pos = url.find('+', pos + 1)) != string::npos) { + url.replace(pos, 1, 1, ' '); + } + pos = 0; + while ((pos = url.find('%', pos + 1)) != string::npos) { + const char *num = url.substr(pos + 1, 2).c_str(); + auto c = (char) strtol(num, nullptr, 16); + url.erase(pos, 3); + url.insert(pos, 1, c); + } - return url; + return url; } string url_encode(string url) { - char buff[4]; - for (long pos = 0; pos < url.length(); pos++) { - auto c = (unsigned char) url[pos]; - if (c < ' ' || c > '~' || c == ' ' || c == '#' || c == '?' || c == '&' || c == '=' || c == '\\' || c == '%') { - sprintf(buff, "%%%02X", c); - url.replace(pos, 1, buff); - } - } - return url; + char buff[4]; + for (long pos = 0; pos < url.length(); pos++) { + auto c = (unsigned char) url[pos]; + if (c < ' ' || c > '~' || c == ' ' || c == '#' || c == '?' || c == '&' || c == '=' || c == '\\' || c == '%') { + sprintf(buff, "%%%02X", c); + url.replace(pos, 1, buff); + } + } + return url; } string html_decode(string text) { - return text; + return text; } string html_encode(string text) { - return text; + return text; } string cli_encode(string text) { - char buff[5]; - for (long pos = 0; pos < text.length(); pos++) { - auto c = (unsigned char) text[pos]; - if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == ',' || c == '.' || c == '_' || c == '+' || c == ':' || c == '@' || c == '%' || c == '/' || c == '-')) { - sprintf(buff, "\\%.1s", &c); - text.replace(pos, 1, buff); - pos++; - } - } - return text; + char buff[5]; + for (long pos = 0; pos < text.length(); pos++) { + auto c = (unsigned char) text[pos]; + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == ',' || c == '.' || c == '_' || c == '+' || c == ':' || c == '@' || c == '%' || c == '/' || c == '-')) { + sprintf(buff, "\\%.1s", &c); + text.replace(pos, 1, buff); + pos++; + } + } + return text; } string read_line(FILE* file) { - char *line; - size_t len = 0; - ssize_t read; - if ((read = getline(&line, &len, file)) < 0 || line == nullptr) { - return ""; - } - string l = string(line); - if (l[l.length()-1] == '\n') { - l.erase(l.length()-1); - } - if (l[l.length()-1] == '\r') { - l.erase(l.length()-1); - } - return l; + char *line; + size_t len = 0; + ssize_t read; + if ((read = getline(&line, &len, file)) < 0 || line == nullptr) { + return ""; + } + string l = string(line); + if (l[l.length()-1] == '\n') { + l.erase(l.length()-1); + } + if (l[l.length()-1] == '\r') { + l.erase(l.length()-1); + } + return l; } @@ -191,12 +191,12 @@ string read_line(FILE* file) { #include "network/http/HttpConnection.cpp" string getWebRoot(string host) { - string root = webroot + host; - if (fileExists(root)) { - return root; - } else { - return ""; - } + string root = webroot + host; + if (fileExists(root)) { + return root; + } else { + return ""; + } } @@ -206,79 +206,79 @@ string getWebRoot(string host) { long clientnum = 0; int main() { - cout << "Necronda Server 3.0" << endl << "by Lorenz Stechauner" << endl << endl; + cout << "Necronda Server 3.0" << endl << "by Lorenz Stechauner" << endl << endl; - signal(SIGPIPE, SIG_IGN); + signal(SIGPIPE, SIG_IGN); - SSL_load_error_strings(); - SSL_library_init(); - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); + SSL_load_error_strings(); + SSL_library_init(); + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); - int ret = system("mkdir -p /var/necronda /etc/necronda /tmp/necronda; touch /var/necronda/ETags"); + int ret = system("mkdir -p /var/necronda /etc/necronda /tmp/necronda; touch /var/necronda/ETags"); - if (ret != 0) { - cout << "Unable to create server files" << endl; - exit(1); - } + if (ret != 0) { + cout << "Unable to create server files" << endl; + exit(1); + } - list ports = {80, 443}; + list ports = {80, 443}; - list servers = {}; - auto it = ports.begin(); + list servers = {}; + auto it = ports.begin(); - for (int i = 0; i < ports.size(); i++) { - unsigned short port = *it; - advance(it, 1); - Socket server = Socket(); - servers.push_back(server); + for (int i = 0; i < ports.size(); i++) { + unsigned short port = *it; + advance(it, 1); + Socket server = Socket(); + servers.push_back(server); - try { - server.setReuseAddress(true); - server.setReceiveTimeout(0); - server.setSendTimeout(0); - } catch (char *msg) { - cout << "Unable to set socket option: " << msg << endl; - exit(2); - } + try { + server.setReuseAddress(true); + server.setReceiveTimeout(0); + server.setSendTimeout(0); + } catch (char *msg) { + cout << "Unable to set socket option: " << msg << endl; + exit(2); + } - try { - server.bind(port); - } catch (char *msg) { - cout << "Unable to bind socket to port " << port << ": " << msg << endl; - exit(3); - } + try { + server.bind(port); + } catch (char *msg) { + cout << "Unable to bind socket to port " << port << ": " << msg << endl; + exit(3); + } - try { - server.listen(256); - } catch (char *msg) { - cout << "Unable to listen on socket: " << msg << endl; - exit(4); - } + try { + server.listen(256); + } catch (char *msg) { + cout << "Unable to listen on socket: " << msg << endl; + exit(4); + } - } + } - cout << "Ready for connections" << endl; + cout << "Ready for connections" << endl; - while (true) { - try { - Socket::select(servers, {}); - for (Socket server : servers) { - try { - Socket *socket = server.accept(); - clientnum++; - thread *t = new thread(client_handler, socket, clientnum, server.getSocketPort() == 443); - } catch (char *msg) { - // Nothing - } - } - } catch (char *msg) { - cout << "Select: " << msg << endl; - break; - } - } + while (true) { + try { + Socket::select(servers, {}); + for (Socket server : servers) { + try { + Socket *socket = server.accept(); + clientnum++; + thread *t = new thread(client_handler, socket, clientnum, server.getSocketPort() == 443); + } catch (char *msg) { + // Nothing + } + } + } catch (char *msg) { + cout << "Select: " << msg << endl; + break; + } + } - return 0; + return 0; } diff --git a/src/network/Address.cpp b/src/network/Address.cpp index d283ea1..f95384a 100644 --- a/src/network/Address.cpp +++ b/src/network/Address.cpp @@ -14,54 +14,54 @@ Address::Address() { } Address::Address(string addr) { - // TODO + // TODO } Address::Address(struct sockaddr_in *addr) { - address = ntohl(addr->sin_addr.s_addr); + address = ntohl(addr->sin_addr.s_addr); } struct sockaddr_in Address::toStruct(unsigned short port)const { - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(address); - addr.sin_port = htons(port); - return addr; + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(address); + addr.sin_port = htons(port); + return addr; } string Address::toString() const { - struct sockaddr_in addr = toStruct(0); - struct in_addr ipAddr = addr.sin_addr; - return inet_ntoa(ipAddr); + struct sockaddr_in addr = toStruct(0); + struct in_addr ipAddr = addr.sin_addr; + return inet_ntoa(ipAddr); } bool Address::isLocal() { - string a = toString(); - return a.find("127.0.0.") == 0; + string a = toString(); + return a.find("127.0.0.") == 0; } ostream& operator<<(ostream &str, const Address &addr) { - return str << addr.toString(); + return str << addr.toString(); } string operator+(string &str, const Address &addr) { - return str + addr.toString(); + return str + addr.toString(); } string operator+(string &str, const Address *addr) { - return str + addr->toString(); + return str + addr->toString(); } string operator+(const Address &addr, string &str) { - return addr.toString() + str; + return addr.toString() + str; } string operator+(const Address *addr, string &str) { - return addr->toString() + str; + return addr->toString() + str; } diff --git a/src/network/Address.h b/src/network/Address.h index 4583b5c..66a66a4 100644 --- a/src/network/Address.h +++ b/src/network/Address.h @@ -11,20 +11,20 @@ using namespace std; class Address { private: - unsigned int address; + unsigned int address; public: - Address(); + Address(); - explicit Address(string address); + explicit Address(string address); - explicit Address(struct sockaddr_in *address); + explicit Address(struct sockaddr_in *address); - struct sockaddr_in toStruct(unsigned short port) const; + struct sockaddr_in toStruct(unsigned short port) const; - string toString() const; + string toString() const; - bool isLocal(); + bool isLocal(); }; diff --git a/src/network/Socket.cpp b/src/network/Socket.cpp index fe3e1ea..26d7a7b 100644 --- a/src/network/Socket.cpp +++ b/src/network/Socket.cpp @@ -29,120 +29,120 @@ using namespace std; static void multi_ssl_init() { - SSL_load_error_strings(); - SSL_library_init(); - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); + SSL_load_error_strings(); + SSL_library_init(); + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); } char *multi_ssl_get_error(SSL *ssl, int ret) { - if (ret > 0) { - return nullptr; - } + if (ret > 0) { + return nullptr; + } - unsigned long ret2 = ERR_get_error(); - const char *err2 = strerror(errno); - const char *err1 = ERR_reason_error_string(ret2); + unsigned long ret2 = ERR_get_error(); + const char *err2 = strerror(errno); + const char *err1 = ERR_reason_error_string(ret2); - switch (SSL_get_error(ssl, ret)) { - case SSL_ERROR_NONE: - return (char *) "none"; - case SSL_ERROR_ZERO_RETURN: - return (char *) "closed"; - case SSL_ERROR_WANT_READ: - return (char *) "want_read"; - case SSL_ERROR_WANT_WRITE: - return (char *) "want_write"; - case SSL_ERROR_WANT_CONNECT: - return (char *) "want_connect"; - case SSL_ERROR_WANT_ACCEPT: - return (char *) "want_accept"; - case SSL_ERROR_WANT_X509_LOOKUP: - return (char *) "want_x509_lookup"; - case SSL_ERROR_SYSCALL: - return (char *) ((ret2 == 0) ? (ret == 0) ? "protocol violation" : err2 : err1); - case SSL_ERROR_SSL: - return (char *) err1; - default: - return (char *) "unknown error"; - } + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_NONE: + return (char *) "none"; + case SSL_ERROR_ZERO_RETURN: + return (char *) "closed"; + case SSL_ERROR_WANT_READ: + return (char *) "want_read"; + case SSL_ERROR_WANT_WRITE: + return (char *) "want_write"; + case SSL_ERROR_WANT_CONNECT: + return (char *) "want_connect"; + case SSL_ERROR_WANT_ACCEPT: + return (char *) "want_accept"; + case SSL_ERROR_WANT_X509_LOOKUP: + return (char *) "want_x509_lookup"; + case SSL_ERROR_SYSCALL: + return (char *) ((ret2 == 0) ? (ret == 0) ? "protocol violation" : err2 : err1); + case SSL_ERROR_SSL: + return (char *) err1; + default: + return (char *) "unknown error"; + } } char *strerror_socket(int nr) { - if (nr == EAGAIN || nr == EWOULDBLOCK) { - return (char *) "timeout"; - } else if (nr == ECONNRESET) { - return (char *) "closed"; - } else { - return strerror(nr); - } + if (nr == EAGAIN || nr == EWOULDBLOCK) { + return (char *) "timeout"; + } else if (nr == ECONNRESET) { + return (char *) "closed"; + } else { + return strerror(nr); + } } Socket::Socket(int fd) { - this->fd = fd; - microsStart = getMicros(); - microsLast = microsStart; - bytesSent = 0; - bytesReceived = 0; - enc = false; - ssl = nullptr; - ctx = nullptr; - clients = false; - servers = false; + this->fd = fd; + microsStart = getMicros(); + microsLast = microsStart; + bytesSent = 0; + bytesReceived = 0; + enc = false; + ssl = nullptr; + ctx = nullptr; + clients = false; + servers = false; } Socket::Socket() { - fd = ::socket(AF_INET, SOCK_STREAM, 0); - if (fd == 0) { - throw strerror(errno); - } - enc = false; - microsStart = getMicros(); - microsLast = microsStart; - bytesSent = 0; - bytesReceived = 0; - ssl = nullptr; - ctx = nullptr; - clients = false; - servers = false; + fd = ::socket(AF_INET, SOCK_STREAM, 0); + if (fd == 0) { + throw strerror(errno); + } + enc = false; + microsStart = getMicros(); + microsLast = microsStart; + bytesSent = 0; + bytesReceived = 0; + ssl = nullptr; + ctx = nullptr; + clients = false; + servers = false; } void Socket::setSocketOption(int option, bool value = true) { - int val = value ? 1 : 0; + int val = value ? 1 : 0; - if (::setsockopt(fd, SOL_SOCKET, option, &val, sizeof(val)) != 0) { - throw strerror(errno); - } + if (::setsockopt(fd, SOL_SOCKET, option, &val, sizeof(val)) != 0) { + throw strerror(errno); + } } void Socket::bind(Address *address, unsigned short port) { - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; // address. - addr.sin_port = htons(port); + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; // address. + addr.sin_port = htons(port); - if (::bind(fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) { - throw strerror(errno); - } + if (::bind(fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) { + throw strerror(errno); + } } void Socket::bind(unsigned short port) { - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = htons(port); + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(port); - if (::bind(fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) { - throw strerror(errno); - } + if (::bind(fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) { + throw strerror(errno); + } } void Socket::listen(int num) { - if (::listen(fd, num) != 0) { - throw strerror(errno); - } + if (::listen(fd, num) != 0) { + throw strerror(errno); + } } void Socket::connect(Address, unsigned short) { @@ -150,86 +150,86 @@ void Socket::connect(Address, unsigned short) { } Socket* Socket::accept() { - int newfd = ::accept(fd, nullptr, nullptr); - if (newfd < 0) { - throw strerror(errno); - } - Socket *socket = new Socket(newfd); - socket->servers = true; - return socket; + int newfd = ::accept(fd, nullptr, nullptr); + if (newfd < 0) { + throw strerror(errno); + } + Socket *socket = new Socket(newfd); + socket->servers = true; + return socket; } void Socket::close() { - if (isSecured()) { - //SSL_shutdown(ssl); - SSL_free(ssl); - SSL_CTX_free(ctx); - } + if (isSecured()) { + //SSL_shutdown(ssl); + SSL_free(ssl); + SSL_CTX_free(ctx); + } - if (::close(fd) != 0) { - throw strerror(errno); - } + if (::close(fd) != 0) { + throw strerror(errno); + } } Address *Socket::getPeerAddress() const { - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - getpeername(fd, (struct sockaddr *) &addr, &len); - struct sockaddr_in *s = (struct sockaddr_in *) &addr; - return new Address(s); + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + getpeername(fd, (struct sockaddr *) &addr, &len); + struct sockaddr_in *s = (struct sockaddr_in *) &addr; + return new Address(s); } unsigned short Socket::getPeerPort() const { - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - getpeername(fd, (struct sockaddr *) &addr, &len); - return ntohs(((struct sockaddr_in *) &addr)->sin_port); + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + getpeername(fd, (struct sockaddr *) &addr, &len); + return ntohs(((struct sockaddr_in *) &addr)->sin_port); } Address *Socket::getSocketAddress() const { - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - getsockname(fd, (struct sockaddr *) &addr, &len); - struct sockaddr_in *s = (struct sockaddr_in *) &addr; - return new Address(s); + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + getsockname(fd, (struct sockaddr *) &addr, &len); + struct sockaddr_in *s = (struct sockaddr_in *) &addr; + return new Address(s); } unsigned short Socket::getSocketPort() const { - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - getsockname(fd, (struct sockaddr *) &addr, &len); - return ntohs(((struct sockaddr_in *) &addr)->sin_port); + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + getsockname(fd, (struct sockaddr *) &addr, &len); + return ntohs(((struct sockaddr_in *) &addr)->sin_port); } void Socket::setReuseAddress(bool value) { - setSocketOption(SO_REUSEADDR, value); + setSocketOption(SO_REUSEADDR, value); } void Socket::setReusePort(bool value) { - setSocketOption(SO_REUSEPORT, value); + setSocketOption(SO_REUSEPORT, value); } string Socket::toString() const { - return "{[Socket]" + getSocketAddress()->toString() + ":" + to_string(getSocketPort()) + "<->" + - getPeerAddress()->toString() + ":" + to_string(getPeerPort()) + "}"; + return "{[Socket]" + getSocketAddress()->toString() + ":" + to_string(getSocketPort()) + "<->" + + getPeerAddress()->toString() + ":" + to_string(getPeerPort()) + "}"; } long Socket::send(string *str) { - return send(str->c_str(), str->length()); + return send(str->c_str(), str->length()); } long Socket::send(string str) { - return send(str.c_str(), str.length()); + return send(str.c_str(), str.length()); } long Socket::send(const char *str, long length) { - return send((void*) str, length); + return send((void*) str, length); } long Socket::send(const char *str) { - return send(str, strlen(str)); + return send(str, strlen(str)); } Socket::~Socket() { @@ -237,403 +237,403 @@ Socket::~Socket() { } long Socket::receive(void *buffer, int size) { - long len; - if (isSecured()) { - len = SSL_read(ssl, buffer, size); - if (len < 0) { - throw multi_ssl_get_error(ssl, (int) len); - } - } else { - len = recv(fd, buffer, (size_t) size, 0); - if (len < 0) { - throw strerror_socket(errno); - } - } - bytesReceived += len; - return len; + long len; + if (isSecured()) { + len = SSL_read(ssl, buffer, size); + if (len < 0) { + throw multi_ssl_get_error(ssl, (int) len); + } + } else { + len = recv(fd, buffer, (size_t) size, 0); + if (len < 0) { + throw strerror_socket(errno); + } + } + bytesReceived += len; + return len; } long Socket::peek(void *buffer, int size) { - long len; - if (isSecured()) { - len = SSL_peek(ssl, buffer, size); - if (len < 0) { - throw multi_ssl_get_error(ssl, (int) len); - } - } else { - len = recv(fd, buffer, (size_t) size, MSG_PEEK); - if (len < 0) { - throw strerror_socket(errno); - } - } - return len; + long len; + if (isSecured()) { + len = SSL_peek(ssl, buffer, size); + if (len < 0) { + throw multi_ssl_get_error(ssl, (int) len); + } + } else { + len = recv(fd, buffer, (size_t) size, MSG_PEEK); + if (len < 0) { + throw strerror_socket(errno); + } + } + return len; } long Socket::send(void *buffer, int size) { - long len; - if (isSecured()) { - if (size != 0) { - len = SSL_write(ssl, buffer, size); - if (len <= 0) { - throw multi_ssl_get_error(ssl, (int) len); - } - } else { - len = 0; - } - } else { - len = ::send(fd, buffer, (size_t) size, 0); - if (len < 0) { - throw strerror_socket(errno); - } - } - bytesSent += len; - return len; + long len; + if (isSecured()) { + if (size != 0) { + len = SSL_write(ssl, buffer, size); + if (len <= 0) { + throw multi_ssl_get_error(ssl, (int) len); + } + } else { + len = 0; + } + } else { + len = ::send(fd, buffer, (size_t) size, 0); + if (len < 0) { + throw strerror_socket(errno); + } + } + bytesSent += len; + return len; } string Socket::receive() { - string *str = new string(); + string *str = new string(); - char buffer[CPPNET_CHUNK]; - long len = 0; - do { - len = receive((void*) buffer, CPPNET_CHUNK); - str->append(buffer, (unsigned) len); - } while (len > 0 && len == CPPNET_CHUNK); + char buffer[CPPNET_CHUNK]; + long len = 0; + do { + len = receive((void*) buffer, CPPNET_CHUNK); + str->append(buffer, (unsigned) len); + } while (len > 0 && len == CPPNET_CHUNK); - return *str; + return *str; } string Socket::receive(long length) { - string *str = new string(); + string *str = new string(); - char buffer[CPPNET_CHUNK]; - long len = 0; - long reclen = 0; - do { - len = receive((void*) buffer, CPPNET_CHUNK); - reclen += len; - str->append(buffer, (unsigned) len); - } while (reclen < length); + char buffer[CPPNET_CHUNK]; + long len = 0; + long reclen = 0; + do { + len = receive((void*) buffer, CPPNET_CHUNK); + reclen += len; + str->append(buffer, (unsigned) len); + } while (reclen < length); - return *str; + return *str; } string Socket::receive(string until) { - string *str = new string(); + string *str = new string(); - struct pollfd ufds[1]; - ufds[0].fd = fd; - ufds[0].events = POLLIN | POLLOUT; + struct pollfd ufds[1]; + ufds[0].fd = fd; + ufds[0].events = POLLIN | POLLOUT; - char buffer[CPPNET_CHUNK]; - long len = 0; - do { - len = peek((void*) buffer, CPPNET_CHUNK); - if (len != 0) { - string s = string(buffer, (size_t) len); - size_t found = s.find(until); - long l = (found != string::npos) ? found + 1 : len; - long l2 = (found != string::npos) ? found : len; - str->append(buffer, (unsigned) l2); - receive((void *) buffer, (int) l); - if (found != string::npos) { - break; - } - } - if (poll(ufds, 1, 0) < 0) { - throw strerror_socket(errno); - } else if ((ufds[0].revents & POLLIN) == 0) { - if ((ufds[0].revents & POLLOUT) != 0) { - throw (char *) "error"; - } else { - throw (char *) "want_write"; - } - } else if ((ufds[0].revents & POLLERR) != 0) { - throw (char *) "error"; - } else if (ufds[0].revents & (POLLRDHUP | POLLHUP | POLLNVAL) != 0) { - throw (char *) "closed"; - } - } while (true); + char buffer[CPPNET_CHUNK]; + long len = 0; + do { + len = peek((void*) buffer, CPPNET_CHUNK); + if (len != 0) { + string s = string(buffer, (size_t) len); + size_t found = s.find(until); + long l = (found != string::npos) ? found + 1 : len; + long l2 = (found != string::npos) ? found : len; + str->append(buffer, (unsigned) l2); + receive((void *) buffer, (int) l); + if (found != string::npos) { + break; + } + } + if (poll(ufds, 1, 0) < 0) { + throw strerror_socket(errno); + } else if ((ufds[0].revents & POLLIN) == 0) { + if ((ufds[0].revents & POLLOUT) != 0) { + throw (char *) "error"; + } else { + throw (char *) "want_write"; + } + } else if ((ufds[0].revents & POLLERR) != 0) { + throw (char *) "error"; + } else if (ufds[0].revents & (POLLRDHUP | POLLHUP | POLLNVAL) != 0) { + throw (char *) "closed"; + } + } while (true); - return *str; + return *str; } string Socket::receive(const char *until) { - return receive(until, (int) (strlen(until))); + return receive(until, (int) (strlen(until))); } string Socket::receive(const char *until, unsigned long strlen) { - return receive(string(until, strlen)); + return receive(string(until, strlen)); } void Socket::receive(FILE *file) { - char buffer[CPPNET_CHUNK]; - long len = 0; - do { - len = receive((void*) buffer, CPPNET_CHUNK); - fwrite(buffer, 1, CPPNET_CHUNK, file); - } while (len > 0 && len == CPPNET_CHUNK); + char buffer[CPPNET_CHUNK]; + long len = 0; + do { + len = receive((void*) buffer, CPPNET_CHUNK); + fwrite(buffer, 1, CPPNET_CHUNK, file); + } while (len > 0 && len == CPPNET_CHUNK); } void Socket::receive(FILE *file, long size) { - char buffer[CPPNET_CHUNK]; - long len = 0; - long rec = 0; - while (size > rec) { - len = receive((void*) buffer, (CPPNET_CHUNK > (size - rec) && size >= 0)?(size - rec):CPPNET_CHUNK); - fwrite(buffer, 1, len, file); - rec += len; - } + char buffer[CPPNET_CHUNK]; + long len = 0; + long rec = 0; + while (size > rec) { + len = receive((void*) buffer, (CPPNET_CHUNK > (size - rec) && size >= 0)?(size - rec):CPPNET_CHUNK); + fwrite(buffer, 1, len, file); + rec += len; + } } string Socket::receiveLine() { - string str = receive("\n"); - if (str.length() > 0 && str.at(str.length() - 1) == '\r') { - str = str.substr(0, str.length() - 1); - } - return str; + string str = receive("\n"); + if (str.length() > 0 && str.at(str.length() - 1) == '\r') { + str = str.substr(0, str.length() - 1); + } + return str; } long Socket::getDuration() { - return getMicros() - microsStart; + return getMicros() - microsStart; } void Socket::setReceiveTimeout(unsigned long ms) { - struct timeval timeout; - if (ms == 0) { - timeout.tv_sec = 0; - timeout.tv_usec = 1; - } else { - timeout.tv_sec = ms / 1000; - timeout.tv_usec = (ms % 1000) * 1000; - } - if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof(timeout)) < 0) { - throw strerror(errno); - } + struct timeval timeout; + if (ms == 0) { + timeout.tv_sec = 0; + timeout.tv_usec = 1; + } else { + timeout.tv_sec = ms / 1000; + timeout.tv_usec = (ms % 1000) * 1000; + } + if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof(timeout)) < 0) { + throw strerror(errno); + } } void Socket::setSendTimeout(unsigned long ms) { - struct timeval timeout; - if (ms == 0) { - timeout.tv_sec = 0; - timeout.tv_usec = 1; - } else { - timeout.tv_sec = ms / 1000; - timeout.tv_usec = (ms % 1000) * 1000; - } - if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(timeout)) < 0) { - throw strerror(errno); - } + struct timeval timeout; + if (ms == 0) { + timeout.tv_sec = 0; + timeout.tv_usec = 1; + } else { + timeout.tv_sec = ms / 1000; + timeout.tv_usec = (ms % 1000) * 1000; + } + if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(timeout)) < 0) { + throw strerror(errno); + } } bool Socket::isServerSide() { - return servers; + return servers; } bool Socket::isSecured() { - return enc; + return enc; } bool Socket::isClientSide() { - return clients; + return clients; } void Socket::sslHandshake(map sni) { - /*if (isSecured()) { - throw (char *) "Socket already secured"; - } + /*if (isSecured()) { + throw (char *) "Socket already secured"; + } - const SSL_METHOD *method; - if (isServerSide()) { - method = TLSv1_2_server_method(); - } else if (isClientSide()) { - method = TLSv1_2_client_method(); - } else { - method = TLSv1_2_method(); - } + const SSL_METHOD *method; + if (isServerSide()) { + method = TLSv1_2_server_method(); + } else if (isClientSide()) { + method = TLSv1_2_client_method(); + } else { + method = TLSv1_2_method(); + } - SSL_CTX *ctx = SSL_CTX_new(method); - SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); - SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); - SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4"); - SSL_CTX_set_ecdh_auto(ctx, 1); + SSL_CTX *ctx = SSL_CTX_new(method); + SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); + SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); + SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4"); + SSL_CTX_set_ecdh_auto(ctx, 1); - const char *certfile = keypair.fullchain.c_str(); - const char *keyfile = keypair.privkey.c_str(); + const char *certfile = keypair.fullchain.c_str(); + const char *keyfile = keypair.privkey.c_str(); - if (isServerSide()) { - if (SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM) != 1) { - throw (char *) ERR_reason_error_string(ERR_get_error()); - } + if (isServerSide()) { + if (SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM) != 1) { + throw (char *) ERR_reason_error_string(ERR_get_error()); + } - if (SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM) != 1) { - throw (char *) ERR_reason_error_string(ERR_get_error()); - } - } + if (SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM) != 1) { + throw (char *) ERR_reason_error_string(ERR_get_error()); + } + } - SSL_CTX_set_tlsext_servername_callback + SSL_CTX_set_tlsext_servername_callback - this->ctx = ctx; - this->ssl = SSL_new(ctx); - SSL_set_fd(ssl, fd); - enc = true; + this->ctx = ctx; + this->ssl = SSL_new(ctx); + SSL_set_fd(ssl, fd); + enc = true; - while (true) { - int ret = 0; - if (isServerSide()) { - ret = SSL_accept(ssl); - } else if (isClientSide()) { - ret = SSL_connect(ssl); - } else { - ret = SSL_do_handshake(ssl); - } + while (true) { + int ret = 0; + if (isServerSide()) { + ret = SSL_accept(ssl); + } else if (isClientSide()) { + ret = SSL_connect(ssl); + } else { + ret = SSL_do_handshake(ssl); + } - if (ret <= 0 && ((isServerSide() && SSL_get_error(ssl, ret) != SSL_ERROR_WANT_READ) || - (isClientSide() && SSL_get_error(ssl, ret) != SSL_ERROR_WANT_WRITE))) { - throw multi_ssl_get_error(ssl, ret); - } else if (ret == 1) { - break; - } - }*/ + if (ret <= 0 && ((isServerSide() && SSL_get_error(ssl, ret) != SSL_ERROR_WANT_READ) || + (isClientSide() && SSL_get_error(ssl, ret) != SSL_ERROR_WANT_WRITE))) { + throw multi_ssl_get_error(ssl, ret); + } else if (ret == 1) { + break; + } + }*/ } void Socket::sslHandshake() { - sslHandshake(KeyPair{"", ""}); + sslHandshake(KeyPair{"", ""}); } void Socket::sslHandshake(KeyPair keypair) { - if (isSecured()) { - throw (char *) "Socket already secured"; - } + if (isSecured()) { + throw (char *) "Socket already secured"; + } - const SSL_METHOD *method; - if (isServerSide()) { - method = TLSv1_2_server_method(); - } else if (isClientSide()) { - method = TLSv1_2_client_method(); - } else { - method = TLSv1_2_method(); - } + const SSL_METHOD *method; + if (isServerSide()) { + method = TLSv1_2_server_method(); + } else if (isClientSide()) { + method = TLSv1_2_client_method(); + } else { + method = TLSv1_2_method(); + } - SSL_CTX *ctx = SSL_CTX_new(method); - SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); - SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, nullptr); - SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION); // TLS1_VERSION - SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); - SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4"); - SSL_CTX_set_ecdh_auto(ctx, 1); + SSL_CTX *ctx = SSL_CTX_new(method); + SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); + SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, nullptr); + SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION); // TLS1_VERSION + SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); + SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4"); + SSL_CTX_set_ecdh_auto(ctx, 1); - const char *certfile = keypair.fullchain.c_str(); - const char *keyfile = keypair.privkey.c_str(); + const char *certfile = keypair.fullchain.c_str(); + const char *keyfile = keypair.privkey.c_str(); - if (isServerSide()) { - if (SSL_CTX_use_certificate_chain_file(ctx, certfile) != 1) { - throw (char *) ERR_reason_error_string(ERR_get_error()); - } + if (isServerSide()) { + if (SSL_CTX_use_certificate_chain_file(ctx, certfile) != 1) { + throw (char *) ERR_reason_error_string(ERR_get_error()); + } - if (SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM) != 1) { - throw (char *) ERR_reason_error_string(ERR_get_error()); - } - } + if (SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM) != 1) { + throw (char *) ERR_reason_error_string(ERR_get_error()); + } + } - this->ctx = ctx; - this->ssl = SSL_new(ctx); - SSL_set_fd(ssl, fd); - enc = true; + this->ctx = ctx; + this->ssl = SSL_new(ctx); + SSL_set_fd(ssl, fd); + enc = true; - while (true) { - int ret = 0; - if (isServerSide()) { - ret = SSL_accept(ssl); - } else if (isClientSide()) { - ret = SSL_connect(ssl); - } else { - ret = SSL_do_handshake(ssl); - } + while (true) { + int ret = 0; + if (isServerSide()) { + ret = SSL_accept(ssl); + } else if (isClientSide()) { + ret = SSL_connect(ssl); + } else { + ret = SSL_do_handshake(ssl); + } - if (ret <= 0 && ((isServerSide() && SSL_get_error(ssl, ret) != SSL_ERROR_WANT_READ) || - (isClientSide() && SSL_get_error(ssl, ret) != SSL_ERROR_WANT_WRITE))) { - throw multi_ssl_get_error(ssl, ret); - } else if (ret == 1) { - break; - } - } + if (ret <= 0 && ((isServerSide() && SSL_get_error(ssl, ret) != SSL_ERROR_WANT_READ) || + (isClientSide() && SSL_get_error(ssl, ret) != SSL_ERROR_WANT_WRITE))) { + throw multi_ssl_get_error(ssl, ret); + } else if (ret == 1) { + break; + } + } } void Socket::sslHandshake(string privkey, string fullchain) { - sslHandshake(KeyPair{std::move(privkey), std::move(fullchain)}); + sslHandshake(KeyPair{std::move(privkey), std::move(fullchain)}); } long Socket::select(list read, list write, long millis) { - fd_set readfd, writefd; - int maxfd = 0; - FD_ZERO(&readfd); - FD_ZERO(&writefd); + fd_set readfd, writefd; + int maxfd = 0; + FD_ZERO(&readfd); + FD_ZERO(&writefd); - for (Socket s : read) { - if (s.fd > maxfd) { - maxfd = s.fd; - } - FD_SET(s.fd, &readfd); - } + for (Socket s : read) { + if (s.fd > maxfd) { + maxfd = s.fd; + } + FD_SET(s.fd, &readfd); + } - for (Socket s : write) { - if (s.fd > maxfd) { - maxfd = s.fd; - } - FD_SET(s.fd, &writefd); - } + for (Socket s : write) { + if (s.fd > maxfd) { + maxfd = s.fd; + } + FD_SET(s.fd, &writefd); + } - struct timeval *tv = new struct timeval; - if (millis < 0) { - tv = nullptr; - } else if (millis == 0) { - tv->tv_sec = 0; - tv->tv_usec = 1; - } else { - tv->tv_sec = millis / 1000; - tv->tv_usec = (millis % 1000) * 1000; - } + struct timeval *tv = new struct timeval; + if (millis < 0) { + tv = nullptr; + } else if (millis == 0) { + tv->tv_sec = 0; + tv->tv_usec = 1; + } else { + tv->tv_sec = millis / 1000; + tv->tv_usec = (millis % 1000) * 1000; + } - int ret = ::select(maxfd + 1, &readfd, &writefd, nullptr, tv); - if (ret < 0) { - throw (char *) strerror(errno); - } - return ret; + int ret = ::select(maxfd + 1, &readfd, &writefd, nullptr, tv); + if (ret < 0) { + throw (char *) strerror(errno); + } + return ret; } long Socket::select(list read, list write) { - Socket::select(std::move(read), std::move(write), -1); + Socket::select(std::move(read), std::move(write), -1); } unsigned long Socket::getBytesSent() { - return bytesSent; + return bytesSent; } unsigned long Socket::getBytesReceived() { - return bytesReceived; + return bytesReceived; } ostream &operator<<(ostream &str, const Socket &socket) { - return str << socket.toString(); + return str << socket.toString(); } ostream &operator<<(ostream &str, const Socket *socket) { - return str << socket->toString(); + return str << socket->toString(); } string operator+(string &str, const Socket &socket) { - return str + socket.toString(); + return str + socket.toString(); } string operator+(const Socket &socket, string &str) { - return socket.toString() + str; + return socket.toString() + str; } diff --git a/src/network/Socket.h b/src/network/Socket.h index 375ff4b..7987441 100644 --- a/src/network/Socket.h +++ b/src/network/Socket.h @@ -12,8 +12,8 @@ #define CPPNET_CHUNK 16384 typedef struct { - string privkey; - string fullchain; + string privkey; + string fullchain; } KeyPair; using namespace std; @@ -21,138 +21,138 @@ using namespace std; class Socket { private: - int fd; - SSL *ssl; - SSL_CTX *ctx; - bool enc; - bool servers; - bool clients; - unsigned long bytesSent; - unsigned long bytesReceived; - long microsStart; - long microsLast; + int fd; + SSL *ssl; + SSL_CTX *ctx; + bool enc; + bool servers; + bool clients; + unsigned long bytesSent; + unsigned long bytesReceived; + long microsStart; + long microsLast; - void setSocketOption(int, bool); + void setSocketOption(int, bool); - long send(void *buffer, int size); + long send(void *buffer, int size); - long receive(void *buffer, int size); + long receive(void *buffer, int size); - long peek(void *buffer, int size); + long peek(void *buffer, int size); public: - Socket(); + Socket(); - explicit Socket(int filedescriptor); + explicit Socket(int filedescriptor); - ~Socket(); + ~Socket(); - void bind(Address *address, unsigned short port); + void bind(Address *address, unsigned short port); - void bind(unsigned short port); + void bind(unsigned short port); - void listen(int count = 1); + void listen(int count = 1); - void connect(Address address, unsigned short port); + void connect(Address address, unsigned short port); - Socket* accept(); + Socket* accept(); - void sslHandshake(); + void sslHandshake(); - void sslHandshake(map sni); + void sslHandshake(map sni); - void sslHandshake(KeyPair keypair); + void sslHandshake(KeyPair keypair); - void sslHandshake(string privkey, string fullchain); + void sslHandshake(string privkey, string fullchain); - long send(string *str); + long send(string *str); - long send(string str); + long send(string str); - long send(const char *str); + long send(const char *str); - long send(const char *str, long length); + long send(const char *str, long length); - string receive(); + string receive(); - string receive(long length); + string receive(long length); - string receive(string until); + string receive(string until); - string receive(const char *until, unsigned long strlen); + string receive(const char *until, unsigned long strlen); - string receive(const char *until); + string receive(const char *until); - void receive(FILE *file); + void receive(FILE *file); - string receiveLine(); + string receiveLine(); - void shutdown(); + void shutdown(); - void close(); + void close(); - long getDuration(); + long getDuration(); - Address *getSocketAddress() const; + Address *getSocketAddress() const; - unsigned short getSocketPort() const; + unsigned short getSocketPort() const; - Address *getPeerAddress() const; + Address *getPeerAddress() const; - unsigned short getPeerPort() const; + unsigned short getPeerPort() const; - string toString() const; + string toString() const; - bool isServerSide(); + bool isServerSide(); - bool isClientSide(); + bool isClientSide(); - bool isSecured(); + bool isSecured(); - void setReuseAddress(bool value = true); + void setReuseAddress(bool value = true); - void setReusePort(bool value = true); + void setReusePort(bool value = true); - void setSendBufferSize(int value); + void setSendBufferSize(int value); - void setReceiveBufferSize(int value); + void setReceiveBufferSize(int value); - void setMinReceiveBytes(int value); + void setMinReceiveBytes(int value); - void setMinSendBytes(int value); + void setMinSendBytes(int value); - void setSendTimeout(unsigned long ms); + void setSendTimeout(unsigned long ms); - void setReceiveTimeout(unsigned long ms); + void setReceiveTimeout(unsigned long ms); - bool getReuseAddress(); + bool getReuseAddress(); - bool getReusePort(); + bool getReusePort(); - int getSendBufferSize(); + int getSendBufferSize(); - int getReceiveBufferSize(); + int getReceiveBufferSize(); - int getMinReceiveBytes(); + int getMinReceiveBytes(); - int getMinSendBytes(); + int getMinSendBytes(); - long getSendTimeout(); + long getSendTimeout(); - long getReceiveTimeout(); + long getReceiveTimeout(); - unsigned long getBytesSent(); + unsigned long getBytesSent(); - unsigned long getBytesReceived(); + unsigned long getBytesReceived(); - static long select(list read, list write, long millis); + static long select(list read, list write, long millis); - static long select(list read, list write); + static long select(list read, list write); - void receive(FILE *file, long size); + void receive(FILE *file, long size); }; Socket operator<<(Socket sock, const char *str); diff --git a/src/network/http/Http.cpp b/src/network/http/Http.cpp index c28211f..505e260 100644 --- a/src/network/http/Http.cpp +++ b/src/network/http/Http.cpp @@ -7,26 +7,26 @@ #include "Http.h" unsigned long getMicros() { - struct timeval tv; - gettimeofday(&tv, nullptr); - return (unsigned long) (1000000 * tv.tv_sec + tv.tv_usec); + struct timeval tv; + gettimeofday(&tv, nullptr); + return (unsigned long) (1000000 * tv.tv_sec + tv.tv_usec); } string getHttpDate() { - time_t rawtime; - time(&rawtime); - return getHttpDate(rawtime); + time_t rawtime; + time(&rawtime); + return getHttpDate(rawtime); } string getHttpDate(string filename) { - struct stat attrib; - stat(filename.c_str(), &attrib); - return getHttpDate(attrib.st_ctime); + struct stat attrib; + stat(filename.c_str(), &attrib); + return getHttpDate(attrib.st_ctime); } string getHttpDate(time_t time) { - char buffer[64]; - struct tm *timeinfo = gmtime(&time); - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S GMT", timeinfo); - return string(buffer); + char buffer[64]; + struct tm *timeinfo = gmtime(&time); + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S GMT", timeinfo); + return string(buffer); } diff --git a/src/network/http/HttpConnection.cpp b/src/network/http/HttpConnection.cpp index f739221..e663c6a 100644 --- a/src/network/http/HttpConnection.cpp +++ b/src/network/http/HttpConnection.cpp @@ -10,184 +10,184 @@ #include "Http.h" HttpConnection::HttpConnection(Socket *socket) { - this->socket = socket; - this->request = new HttpRequest(socket); - this->response = new HttpResponse(); - microsStart = getMicros(); - response->setVersion("1.1"); - response->setField("Server", "Necronda/3.0"); + this->socket = socket; + this->request = new HttpRequest(socket); + this->response = new HttpResponse(); + microsStart = getMicros(); + response->setVersion("1.1"); + response->setField("Server", "Necronda/3.0"); } void HttpConnection::respond(int statuscode) { - if (statuscode >= 400 && statuscode < 600) { - respond(statuscode, - "" + to_string(statuscode) + " " + - ::getStatusCode(statuscode).message + - "

" + to_string(statuscode) + " " + - ::getStatusCode(statuscode).message + - "

" + - ((request->isExistingField("Host")) ? - (request->isExistingField("Referer") && - request->getField("Referer").find(request->getField("Host")) != string::npos) ? - "

Go back to the last page you visited: getField("Referer") + "\">" + - request->getField("Referer") + "

" : - "

Go back to the home page of getField("Host") + "/\">" + - request->getField("Host") + - "

" : "") + "
\r\n" - ); - } else { - respond(statuscode, ""); - } + if (statuscode >= 400 && statuscode < 600) { + respond(statuscode, + "" + to_string(statuscode) + " " + + ::getStatusCode(statuscode).message + + "

" + to_string(statuscode) + " " + + ::getStatusCode(statuscode).message + + "

" + + ((request->isExistingField("Host")) ? + (request->isExistingField("Referer") && + request->getField("Referer").find(request->getField("Host")) != string::npos) ? + "

Go back to the last page you visited: getField("Referer") + "\">" + + request->getField("Referer") + "

" : + "

Go back to the home page of getField("Host") + "/\">" + + request->getField("Host") + + "

" : "") + "
\r\n" + ); + } else { + respond(statuscode, ""); + } } void HttpConnection::respond(int statuscode, string payload) { - response->setStatusCode(statuscode); - response->setField("Date", getHttpDate()); - response->setField("Content-Length", to_string(payload.length())); - response->sendHeader(socket); - socket->send(std::move(payload)); + response->setStatusCode(statuscode); + response->setField("Date", getHttpDate()); + response->setField("Content-Length", to_string(payload.length())); + response->sendHeader(socket); + socket->send(std::move(payload)); } void HttpConnection::respond(int statuscode, FILE *file, bool compress, long start, long end) { - response->setStatusCode(statuscode); - response->setField("Transfer-Encoding", "chunked"); - response->setField("Date", getHttpDate()); + response->setStatusCode(statuscode); + response->setField("Transfer-Encoding", "chunked"); + response->setField("Date", getHttpDate()); - long shouldTransfer; - long transfered = 0; + long shouldTransfer; + long transfered = 0; - fseek(file, 0, SEEK_END); - long len = ftell(file); + fseek(file, 0, SEEK_END); + long len = ftell(file); - if (start != -1 && end != -1) { - fseek(file, start, SEEK_SET); - response->setField("Content-Length", to_string(end - start + 1)); - shouldTransfer = end - start + 1; - compress = false; - } else { - fseek(file, 0, SEEK_SET); - shouldTransfer = len; - if (len >= 0 && !compress) { - response->setField("Content-Length", to_string(len)); - } - } + if (start != -1 && end != -1) { + fseek(file, start, SEEK_SET); + response->setField("Content-Length", to_string(end - start + 1)); + shouldTransfer = end - start + 1; + compress = false; + } else { + fseek(file, 0, SEEK_SET); + shouldTransfer = len; + if (len >= 0 && !compress) { + response->setField("Content-Length", to_string(len)); + } + } - if (compress) { - response->setField("Content-Encoding", "deflate"); - } + if (compress) { + response->setField("Content-Encoding", "deflate"); + } - response->sendHeader(socket); + response->sendHeader(socket); - if (compress) { - int level = 1; - int ret, flush; - unsigned have; - z_stream strm; - unsigned char in[CPPNET_CHUNK]; - unsigned char out[CPPNET_CHUNK]; + if (compress) { + int level = 1; + int ret, flush; + unsigned have; + z_stream strm; + unsigned char in[CPPNET_CHUNK]; + unsigned char out[CPPNET_CHUNK]; - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - ret = deflateInit(&strm, level); - if (ret != Z_OK) { - throw (char *) "Unable to open file"; - } + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit(&strm, level); + if (ret != Z_OK) { + throw (char *) "Unable to open file"; + } - do { - strm.avail_in = (uInt) fread(in, 1, CPPNET_CHUNK, file); + do { + strm.avail_in = (uInt) fread(in, 1, CPPNET_CHUNK, file); - if (ferror(file)) { - (void) deflateEnd(&strm); - throw (char *) strerror(errno); - } - flush = feof(file) ? Z_FINISH : Z_NO_FLUSH; - strm.next_in = in; - do { - strm.avail_out = CPPNET_CHUNK; - strm.next_out = out; - ret = deflate(&strm, flush); - assert(ret != Z_STREAM_ERROR); - have = CPPNET_CHUNK - strm.avail_out; + if (ferror(file)) { + (void) deflateEnd(&strm); + throw (char *) strerror(errno); + } + flush = feof(file) ? Z_FINISH : Z_NO_FLUSH; + strm.next_in = in; + do { + strm.avail_out = CPPNET_CHUNK; + strm.next_out = out; + ret = deflate(&strm, flush); + assert(ret != Z_STREAM_ERROR); + have = CPPNET_CHUNK - strm.avail_out; - if (have != 0) { - char buffer[64]; - sprintf(buffer, "%X\r\n", have); - socket->send(buffer); - socket->send((const char *) out, have); - socket->send("\r\n"); - } - } while (strm.avail_out == 0); - assert(strm.avail_in == 0); - } while (flush != Z_FINISH); - assert(ret == Z_STREAM_END); - socket->send("0\r\n\r\n"); - deflateEnd(&strm); - } else { - char buffer[CPPNET_CHUNK]; - char buff[64]; - while (true) { - unsigned long size = fread(buffer, 1, (size_t) ((CPPNET_CHUNK > (shouldTransfer - transfered) && shouldTransfer > 0) ? (shouldTransfer - transfered) : CPPNET_CHUNK), file); - transfered += size; - sprintf(buff, "%lX\r\n", size); - socket->send(buff); - socket->send((const char *) buffer, size); - socket->send("\r\n"); - if (size == 0) { - break; - } - } - } + if (have != 0) { + char buffer[64]; + sprintf(buffer, "%X\r\n", have); + socket->send(buffer); + socket->send((const char *) out, have); + socket->send("\r\n"); + } + } while (strm.avail_out == 0); + assert(strm.avail_in == 0); + } while (flush != Z_FINISH); + assert(ret == Z_STREAM_END); + socket->send("0\r\n\r\n"); + deflateEnd(&strm); + } else { + char buffer[CPPNET_CHUNK]; + char buff[64]; + while (true) { + unsigned long size = fread(buffer, 1, (size_t) ((CPPNET_CHUNK > (shouldTransfer - transfered) && shouldTransfer > 0) ? (shouldTransfer - transfered) : CPPNET_CHUNK), file); + transfered += size; + sprintf(buff, "%lX\r\n", size); + socket->send(buff); + socket->send((const char *) buffer, size); + socket->send("\r\n"); + if (size == 0) { + break; + } + } + } } string HttpConnection::getField(string index) { - return request->getField(std::move(index)); + return request->getField(std::move(index)); } string HttpConnection::getPath() { - return request->getPath(); + return request->getPath(); } void HttpConnection::setField(string index, string data) { - response->setField(std::move(index), std::move(data)); + response->setField(std::move(index), std::move(data)); } bool HttpConnection::isExistingField(string index) { - return request->isExistingField(std::move(index)); + return request->isExistingField(std::move(index)); } string HttpConnection::getMethod() { - return request->getMethod(); + return request->getMethod(); } long HttpConnection::getDuration() { - return getMicros() - microsStart; + return getMicros() - microsStart; } HttpStatusCode HttpConnection::getStatusCode() { - return response->getStatusCode(); + return response->getStatusCode(); } void HttpConnection::redirect(int statuscode, string location) { - setField("Location", std::move(location)); - respond(statuscode, ""); + setField("Location", std::move(location)); + respond(statuscode, ""); } string HttpConnection::getResponseField(string index) { - return response->getField(std::move(index)); + return response->getField(std::move(index)); } bool HttpConnection::isExistingResponseField(string index) { - return response->isExistingField(std::move(index)); + return response->isExistingField(std::move(index)); } string HttpConnection::cgiExport() { - return request->cgiExport(); + return request->cgiExport(); } void HttpConnection::removeField(string index) { - response->removeField(std::move(index)); + response->removeField(std::move(index)); } diff --git a/src/network/http/HttpConnection.h b/src/network/http/HttpConnection.h index 2cc15b2..ff666e7 100644 --- a/src/network/http/HttpConnection.h +++ b/src/network/http/HttpConnection.h @@ -11,43 +11,43 @@ class HttpConnection { private: - Socket *socket; - HttpRequest *request; - HttpResponse *response; - long microsStart; + Socket *socket; + HttpRequest *request; + HttpResponse *response; + long microsStart; public: - explicit HttpConnection(Socket *socket); + explicit HttpConnection(Socket *socket); - void respond(int statuscode); + void respond(int statuscode); - void respond(int statuscode, string payload); + void respond(int statuscode, string payload); - void respond(int statuscode, FILE *file, bool compress = false, long start = -1, long end = -1); + void respond(int statuscode, FILE *file, bool compress = false, long start = -1, long end = -1); - void redirect(int statuscode, string location); + void redirect(int statuscode, string location); - bool isExistingField(string index); + bool isExistingField(string index); - bool isExistingResponseField(string index); + bool isExistingResponseField(string index); - string getField(string index); + string getField(string index); - string getResponseField(string index); + string getResponseField(string index); - string getPath(); + string getPath(); - string getMethod(); + string getMethod(); - void setField(string index, string data); + void setField(string index, string data); - long getDuration(); + long getDuration(); - HttpStatusCode getStatusCode(); + HttpStatusCode getStatusCode(); - string cgiExport(); + string cgiExport(); - void removeField(string index); + void removeField(string index); }; #endif diff --git a/src/network/http/HttpHeader.cpp b/src/network/http/HttpHeader.cpp index 755aa16..410e46c 100644 --- a/src/network/http/HttpHeader.cpp +++ b/src/network/http/HttpHeader.cpp @@ -15,12 +15,12 @@ using namespace std; string to_cgi(string text) { - for (auto & c: text) c = (char) toupper(c); - long pos = 0; - while ((pos = text.find('-', pos + 1)) != string::npos) { - text.replace(pos, 1, 1, '_'); - } - return text; + for (auto & c: text) c = (char) toupper(c); + long pos = 0; + while ((pos = text.find('-', pos + 1)) != string::npos) { + text.replace(pos, 1, 1, '_'); + } + return text; } @@ -28,33 +28,33 @@ string to_cgi(string text) { * Default Constructor */ HttpHeader::HttpHeader() { - fields = fields; + fields = fields; } HttpHeader::HttpHeader(Socket *socket) : HttpHeader::HttpHeader() { - parse(socket); + parse(socket); } void HttpHeader::parse(Socket *socket) { - while (true) { - string line = socket->receiveLine(); - if (line.length() == 0) { - break; - } else { - unsigned long pos = line.find(':'); - if (pos == string::npos) { - throw (char *) "Malformed header"; - } - string index = line.substr(0, pos); - string data = line.substr(pos + 1, line.length() - pos); - while (index[0] == ' ') index.erase(index.begin() + 0); - while (index[index.length() - 1] == ' ') index.erase(index.end() - 1); - while (data[0] == ' ') data.erase(data.begin() + 0); - while (data[data.length() - 1] == ' ') data.erase(data.end() - 1); - setField(index, data); - } - } + while (true) { + string line = socket->receiveLine(); + if (line.length() == 0) { + break; + } else { + unsigned long pos = line.find(':'); + if (pos == string::npos) { + throw (char *) "Malformed header"; + } + string index = line.substr(0, pos); + string data = line.substr(pos + 1, line.length() - pos); + while (index[0] == ' ') index.erase(index.begin() + 0); + while (index[index.length() - 1] == ' ') index.erase(index.end() - 1); + while (data[0] == ' ') data.erase(data.begin() + 0); + while (data[data.length() - 1] == ' ') data.erase(data.end() - 1); + setField(index, data); + } + } } @@ -62,7 +62,7 @@ void HttpHeader::parse(Socket *socket) { * Default Destructor */ HttpHeader::~HttpHeader() { - fields.clear(); + fields.clear(); } @@ -73,12 +73,12 @@ HttpHeader::~HttpHeader() { * @param data The field data */ void HttpHeader::setField(string index, string data) { - removeField(index); - fields.insert(make_pair(index, data)); + removeField(index); + fields.insert(make_pair(index, data)); } void HttpHeader::removeField(string index) { - fields.erase(index); + fields.erase(index); } /** @@ -88,34 +88,34 @@ void HttpHeader::removeField(string index) { * @return The field data */ string HttpHeader::getField(string index) { - auto i = fields.find(index); - if (i != fields.end()) { - return fields.at(index); - } else { - return ""; - } + auto i = fields.find(index); + if (i != fields.end()) { + return fields.at(index); + } else { + return ""; + } } bool HttpHeader::isExistingField(string index) { - auto i = fields.find(index); - return i != fields.end(); + auto i = fields.find(index); + return i != fields.end(); } string HttpHeader::toString() { - string header = ""; - for (auto it = fields.begin(); it != fields.end(); it++ ) { - header += it->first + ": " + it->second + "\r\n"; - } - return header; + string header = ""; + for (auto it = fields.begin(); it != fields.end(); it++ ) { + header += it->first + ": " + it->second + "\r\n"; + } + return header; } string HttpHeader::cgiExport() { - string header = ""; - for (auto it = fields.begin(); it != fields.end(); it++ ) { - header += "HTTP_" + to_cgi(it->first) + "=" + cli_encode(it->second) + " "; - } - return header; + string header = ""; + for (auto it = fields.begin(); it != fields.end(); it++ ) { + header += "HTTP_" + to_cgi(it->first) + "=" + cli_encode(it->second) + " "; + } + return header; } diff --git a/src/network/http/HttpHeader.h b/src/network/http/HttpHeader.h index 291f434..a6c6116 100644 --- a/src/network/http/HttpHeader.h +++ b/src/network/http/HttpHeader.h @@ -12,9 +12,9 @@ using namespace std; struct comp { - bool operator()(const std::string& lhs, const std::string& rhs) const { - return strcasecmp(lhs.c_str(), rhs.c_str()) < 0; - } + bool operator()(const std::string& lhs, const std::string& rhs) const { + return strcasecmp(lhs.c_str(), rhs.c_str()) < 0; + } }; /** @@ -25,28 +25,28 @@ struct comp { */ class HttpHeader { private: - map fields; + map fields; public: - HttpHeader(); + HttpHeader(); - explicit HttpHeader(Socket *socket); + explicit HttpHeader(Socket *socket); - ~HttpHeader(); + ~HttpHeader(); - void setField(string index, string data); + void setField(string index, string data); - string getField(string index); + string getField(string index); - void removeField(string index); + void removeField(string index); - bool isExistingField(string index); + bool isExistingField(string index); - void parse(Socket *socket); + void parse(Socket *socket); - string toString(); + string toString(); - string cgiExport(); + string cgiExport(); }; diff --git a/src/network/http/HttpRequest.cpp b/src/network/http/HttpRequest.cpp index c323a01..955d359 100644 --- a/src/network/http/HttpRequest.cpp +++ b/src/network/http/HttpRequest.cpp @@ -9,95 +9,95 @@ HttpRequest::HttpRequest() { - this->header = HttpHeader(); + this->header = HttpHeader(); } HttpRequest::HttpRequest(Socket *socket) : HttpRequest::HttpRequest() { - parseHeader(socket); + parseHeader(socket); } HttpRequest::HttpRequest(string method, string path, string version) : HttpRequest::HttpRequest() { - this->method = std::move(method); - this->path = std::move(path); - this->version = std::move(version); + this->method = std::move(method); + this->path = std::move(path); + this->version = std::move(version); } void HttpRequest::parseHeader(Socket *socket) { - string line = socket->receiveLine(); + string line = socket->receiveLine(); - unsigned long pos1 = line.find(' '); - unsigned long pos2; + unsigned long pos1 = line.find(' '); + unsigned long pos2; - bool invalid = false; + bool invalid = false; - if (pos1 != string::npos) { - pos2 = line.find(' ', pos1 + 1); - if (pos2 != string::npos) { - method = line.substr(0, pos1); - for (auto &c: method) c = (char) toupper(c); - path = line.substr(pos1 + 1, pos2 - pos1 - 1); - version = line.substr(pos2 + 6, 3); - } else { - invalid = true; - } - } else { - pos2 = string::npos; - invalid = true; - } + if (pos1 != string::npos) { + pos2 = line.find(' ', pos1 + 1); + if (pos2 != string::npos) { + method = line.substr(0, pos1); + for (auto &c: method) c = (char) toupper(c); + path = line.substr(pos1 + 1, pos2 - pos1 - 1); + version = line.substr(pos2 + 6, 3); + } else { + invalid = true; + } + } else { + pos2 = string::npos; + invalid = true; + } - if (!invalid && (line.substr(pos2 + 1, 5) != "HTTP/" || version[1] != '.' || path[0] != '/' || !(version[0] >= '0' && version[0] <= '9') || !(version[2] >= '0' && version[2] <= '9'))) { - invalid = true; - } + if (!invalid && (line.substr(pos2 + 1, 5) != "HTTP/" || version[1] != '.' || path[0] != '/' || !(version[0] >= '0' && version[0] <= '9') || !(version[2] >= '0' && version[2] <= '9'))) { + invalid = true; + } - if (invalid) { - method = ""; - path = ""; - version = ""; - throw (char *) "Malformed header"; - } + if (invalid) { + method = ""; + path = ""; + version = ""; + throw (char *) "Malformed header"; + } - header.parse(socket); + header.parse(socket); } string HttpRequest::getMethod() { - return method; + return method; } string HttpRequest::getPath() { - return path; + return path; } string HttpRequest::getVersion() { - return version; + return version; } void HttpRequest::setMethod(string method) { - this->method = std::move(method); + this->method = std::move(method); } void HttpRequest::setPath(string path) { - this->path = std::move(path); + this->path = std::move(path); } void HttpRequest::setVersion(string version) { - this->version = std::move(version); + this->version = std::move(version); } string HttpRequest::getField(string index) { - return header.getField(std::move(index)); + return header.getField(std::move(index)); } void HttpRequest::setField(string index, string data) { - header.setField(std::move(index), std::move(data)); + header.setField(std::move(index), std::move(data)); } bool HttpRequest::isExistingField(string index) { - return header.isExistingField(std::move(index)); + return header.isExistingField(std::move(index)); } string HttpRequest::cgiExport() { - return header.cgiExport(); + return header.cgiExport(); } diff --git a/src/network/http/HttpRequest.h b/src/network/http/HttpRequest.h index 1432719..aa0c8f2 100644 --- a/src/network/http/HttpRequest.h +++ b/src/network/http/HttpRequest.h @@ -11,41 +11,41 @@ using namespace std; class HttpRequest { private: - HttpHeader header; - string method; - string path; - string version; + HttpHeader header; + string method; + string path; + string version; public: - HttpRequest(); + HttpRequest(); - explicit HttpRequest(Socket *socket); + explicit HttpRequest(Socket *socket); - HttpRequest(string method, string path, string version = "1.1"); + HttpRequest(string method, string path, string version = "1.1"); - void parseHeader(Socket *socket); + void parseHeader(Socket *socket); - void sendHeader(Socket *socket); + void sendHeader(Socket *socket); - string getField(string index); + string getField(string index); - void setField(string index, string data); + void setField(string index, string data); - bool isExistingField(string index); + bool isExistingField(string index); - string getMethod(); + string getMethod(); - string getPath(); + string getPath(); - string getVersion(); + string getVersion(); - void setMethod(string method); + void setMethod(string method); - void setPath(string path); + void setPath(string path); - void setVersion(string version); + void setVersion(string version); - string cgiExport(); + string cgiExport(); }; diff --git a/src/network/http/HttpResponse.cpp b/src/network/http/HttpResponse.cpp index 83df59e..e07aa2d 100644 --- a/src/network/http/HttpResponse.cpp +++ b/src/network/http/HttpResponse.cpp @@ -9,56 +9,56 @@ HttpResponse::HttpResponse() { - this->header = HttpHeader(); + this->header = HttpHeader(); } HttpResponse::HttpResponse(Socket *socket) : HttpResponse::HttpResponse() { - this->parseHeader(socket); + this->parseHeader(socket); } HttpResponse::HttpResponse(int statuscode, string version) : HttpResponse::HttpResponse(::getStatusCode(statuscode), std::move(version)) { } HttpResponse::HttpResponse(HttpStatusCode statuscode, string version) : HttpResponse::HttpResponse() { - this->statuscode = statuscode; - this->version = std::move(version); + this->statuscode = statuscode; + this->version = std::move(version); } void HttpResponse::sendHeader(Socket *socket) { - socket->send("HTTP/" + version + " " + to_string(statuscode.code) + " " + statuscode.message + "\r\n" + - header.toString() + "\r\n"); + socket->send("HTTP/" + version + " " + to_string(statuscode.code) + " " + statuscode.message + "\r\n" + + header.toString() + "\r\n"); } string HttpResponse::getField(string index) { - return header.getField(std::move(index)); + return header.getField(std::move(index)); } void HttpResponse::setField(string index, string data) { - header.setField(std::move(index), std::move(data)); + header.setField(std::move(index), std::move(data)); } bool HttpResponse::isExistingField(string index) { - return header.isExistingField(std::move(index)); + return header.isExistingField(std::move(index)); } HttpStatusCode HttpResponse::getStatusCode() { - return statuscode; + return statuscode; } string HttpResponse::getVersion() { - return version; + return version; } void HttpResponse::setStatusCode(HttpStatusCode statuscode) { - this->statuscode = statuscode; + this->statuscode = statuscode; } void HttpResponse::setStatusCode(int statuscode) { - this->statuscode = ::getStatusCode(statuscode); + this->statuscode = ::getStatusCode(statuscode); } void HttpResponse::setVersion(string version) { - this->version = std::move(version); + this->version = std::move(version); } void HttpResponse::parseHeader(Socket *socket) { @@ -66,5 +66,5 @@ void HttpResponse::parseHeader(Socket *socket) { } void HttpResponse::removeField(string index) { - header.removeField(std::move(index)); + header.removeField(std::move(index)); } diff --git a/src/network/http/HttpResponse.h b/src/network/http/HttpResponse.h index f664e71..d254724 100644 --- a/src/network/http/HttpResponse.h +++ b/src/network/http/HttpResponse.h @@ -11,40 +11,40 @@ class HttpResponse { private: - HttpHeader header; - HttpStatusCode statuscode; - string version; + HttpHeader header; + HttpStatusCode statuscode; + string version; public: - HttpResponse(); + HttpResponse(); - explicit HttpResponse(Socket *socket); + explicit HttpResponse(Socket *socket); - explicit HttpResponse(int statuscode, string version = "1.1"); + explicit HttpResponse(int statuscode, string version = "1.1"); - explicit HttpResponse(HttpStatusCode statuscode, string version = "1.1"); + explicit HttpResponse(HttpStatusCode statuscode, string version = "1.1"); - void parseHeader(Socket *socket); + void parseHeader(Socket *socket); - void sendHeader(Socket *socket); + void sendHeader(Socket *socket); - string getField(string index); + string getField(string index); - void setField(string index, string data); + void setField(string index, string data); - bool isExistingField(string index); + bool isExistingField(string index); - HttpStatusCode getStatusCode(); + HttpStatusCode getStatusCode(); - string getVersion(); + string getVersion(); - void setStatusCode(HttpStatusCode statuscode); + void setStatusCode(HttpStatusCode statuscode); - void setStatusCode(int statuscode); + void setStatusCode(int statuscode); - void setVersion(string version); + void setVersion(string version); - void removeField(string index); + void removeField(string index); }; #endif diff --git a/src/network/http/HttpStatusCode.cpp b/src/network/http/HttpStatusCode.cpp index bffeafb..82c617a 100644 --- a/src/network/http/HttpStatusCode.cpp +++ b/src/network/http/HttpStatusCode.cpp @@ -9,57 +9,57 @@ HttpStatusCode httpStatusCodes[] = { - HttpStatusCode{100, "Informational", "Continue", ""}, - HttpStatusCode{101, "Informational", "Switching Protocols", ""}, + HttpStatusCode{100, "Informational", "Continue", ""}, + HttpStatusCode{101, "Informational", "Switching Protocols", ""}, - HttpStatusCode{200, "Success", "OK", ""}, - HttpStatusCode{201, "Success", "Created", ""}, - HttpStatusCode{202, "Success", "Accepted", ""}, - HttpStatusCode{203, "Success", "Non-Authoritative Information", ""}, - HttpStatusCode{204, "Success", "No Centent", ""}, - HttpStatusCode{205, "Success", "Reset Content", ""}, - HttpStatusCode{206, "Success", "Partial Content", ""}, + HttpStatusCode{200, "Success", "OK", ""}, + HttpStatusCode{201, "Success", "Created", ""}, + HttpStatusCode{202, "Success", "Accepted", ""}, + HttpStatusCode{203, "Success", "Non-Authoritative Information", ""}, + HttpStatusCode{204, "Success", "No Centent", ""}, + HttpStatusCode{205, "Success", "Reset Content", ""}, + HttpStatusCode{206, "Success", "Partial Content", ""}, - HttpStatusCode{300, "Redirection", "Multiple Choices", ""}, - HttpStatusCode{301, "Redirection", "Moved Permanently", ""}, - HttpStatusCode{302, "Redirection", "Found", ""}, - HttpStatusCode{303, "Redirection", "See Other", ""}, - HttpStatusCode{304, "Redirection", "Not Modified", ""}, - HttpStatusCode{305, "Redirection", "Use Proxy", ""}, - HttpStatusCode{307, "Redirection", "Temporary Redirect", ""}, + HttpStatusCode{300, "Redirection", "Multiple Choices", ""}, + HttpStatusCode{301, "Redirection", "Moved Permanently", ""}, + HttpStatusCode{302, "Redirection", "Found", ""}, + HttpStatusCode{303, "Redirection", "See Other", ""}, + HttpStatusCode{304, "Redirection", "Not Modified", ""}, + HttpStatusCode{305, "Redirection", "Use Proxy", ""}, + HttpStatusCode{307, "Redirection", "Temporary Redirect", ""}, - HttpStatusCode{400, "Client Error", "Bad Request", ""}, - HttpStatusCode{401, "Client Error", "Unauthorized", ""}, - HttpStatusCode{402, "Client Error", "Payment Required", ""}, - HttpStatusCode{403, "Client Error", "Forbidden", ""}, - HttpStatusCode{404, "Client Error", "Not Found", ""}, - HttpStatusCode{405, "Client Error", "Method Not Allowed", ""}, - HttpStatusCode{406, "Client Error", "Not Acceptable", ""}, - HttpStatusCode{407, "Client Error", "Proxy Authentication Required", ""}, - HttpStatusCode{408, "Client Error", "Request Timeout", ""}, - HttpStatusCode{409, "Client Error", "Conflict", ""}, - HttpStatusCode{410, "Client Error", "Gone", ""}, - HttpStatusCode{411, "Client Error", "Length Required", ""}, - HttpStatusCode{412, "Client Error", "Precondition Failed", ""}, - HttpStatusCode{413, "Client Error", "Request Entity Too Large", ""}, - HttpStatusCode{414, "Client Error", "Request-URI Too Long", ""}, - HttpStatusCode{415, "Client Error", "Unsupported Media Type", ""}, - HttpStatusCode{416, "Client Error", "Requested Range Not Satisfiable", ""}, - HttpStatusCode{417, "Client Error", "Expectation Failed", ""}, + HttpStatusCode{400, "Client Error", "Bad Request", ""}, + HttpStatusCode{401, "Client Error", "Unauthorized", ""}, + HttpStatusCode{402, "Client Error", "Payment Required", ""}, + HttpStatusCode{403, "Client Error", "Forbidden", ""}, + HttpStatusCode{404, "Client Error", "Not Found", ""}, + HttpStatusCode{405, "Client Error", "Method Not Allowed", ""}, + HttpStatusCode{406, "Client Error", "Not Acceptable", ""}, + HttpStatusCode{407, "Client Error", "Proxy Authentication Required", ""}, + HttpStatusCode{408, "Client Error", "Request Timeout", ""}, + HttpStatusCode{409, "Client Error", "Conflict", ""}, + HttpStatusCode{410, "Client Error", "Gone", ""}, + HttpStatusCode{411, "Client Error", "Length Required", ""}, + HttpStatusCode{412, "Client Error", "Precondition Failed", ""}, + HttpStatusCode{413, "Client Error", "Request Entity Too Large", ""}, + HttpStatusCode{414, "Client Error", "Request-URI Too Long", ""}, + HttpStatusCode{415, "Client Error", "Unsupported Media Type", ""}, + HttpStatusCode{416, "Client Error", "Requested Range Not Satisfiable", ""}, + HttpStatusCode{417, "Client Error", "Expectation Failed", ""}, - HttpStatusCode{500, "Server Error", "Internal Server Error", ""}, - HttpStatusCode{501, "Server Error", "Not Implemented", ""}, - HttpStatusCode{502, "Server Error", "Bad Gateway", ""}, - HttpStatusCode{503, "Server Error", "Service Unavailable", ""}, - HttpStatusCode{504, "Server Error", "Gateway Timeout", ""}, - HttpStatusCode{505, "Server Error", "HTTP Version Not Supported", ""}, + HttpStatusCode{500, "Server Error", "Internal Server Error", ""}, + HttpStatusCode{501, "Server Error", "Not Implemented", ""}, + HttpStatusCode{502, "Server Error", "Bad Gateway", ""}, + HttpStatusCode{503, "Server Error", "Service Unavailable", ""}, + HttpStatusCode{504, "Server Error", "Gateway Timeout", ""}, + HttpStatusCode{505, "Server Error", "HTTP Version Not Supported", ""}, }; HttpStatusCode getStatusCode(int statuscode) { - for (HttpStatusCode sc : httpStatusCodes) { - if (sc.code == statuscode) { - return sc; - } - } - throw (char *) "Invalid status code"; + for (HttpStatusCode sc : httpStatusCodes) { + if (sc.code == statuscode) { + return sc; + } + } + throw (char *) "Invalid status code"; } diff --git a/src/network/http/HttpStatusCode.h b/src/network/http/HttpStatusCode.h index 7773af9..f04b3c3 100644 --- a/src/network/http/HttpStatusCode.h +++ b/src/network/http/HttpStatusCode.h @@ -4,10 +4,10 @@ #define NECRONDA_HTTP_STATUSCODE typedef struct { - short code; // The status code (e.g. 200) - const char *type; // The status type type (e.g Success) - const char *message; // The status code message (e.g. OK) - const char *description; // The status code description (currently not used) + short code; // The status code (e.g. 200) + const char *type; // The status type type (e.g Success) + const char *message; // The status code message (e.g. OK) + const char *description; // The status code description (currently not used) } HttpStatusCode; HttpStatusCode getStatusCode(int statuscode); diff --git a/src/procopen.cpp b/src/procopen.cpp index 6a53f60..551d689 100644 --- a/src/procopen.cpp +++ b/src/procopen.cpp @@ -6,36 +6,36 @@ stds procopen(const char* command) { - int pipes[3][2]; + int pipes[3][2]; - pipe(pipes[PARENT_READ_PIPE]); - pipe(pipes[PARENT_WRITE_PIPE]); - pipe(pipes[PARENT_ERROR_PIPE]); + pipe(pipes[PARENT_READ_PIPE]); + pipe(pipes[PARENT_WRITE_PIPE]); + pipe(pipes[PARENT_ERROR_PIPE]); - int pid = fork(); + int pid = fork(); - if(pid == 0) { - dup2(CHILD_READ_FD, STDIN_FILENO); - dup2(CHILD_WRITE_FD, STDOUT_FILENO); - dup2(CHILD_ERROR_FD, STDERR_FILENO); + if(pid == 0) { + dup2(CHILD_READ_FD, STDIN_FILENO); + dup2(CHILD_WRITE_FD, STDOUT_FILENO); + dup2(CHILD_ERROR_FD, STDERR_FILENO); - close(CHILD_READ_FD); - close(CHILD_WRITE_FD); - close(CHILD_ERROR_FD); + close(CHILD_READ_FD); + close(CHILD_WRITE_FD); + close(CHILD_ERROR_FD); - close(PARENT_READ_FD); - close(PARENT_WRITE_FD); - close(PARENT_ERROR_FD); + close(PARENT_READ_FD); + close(PARENT_WRITE_FD); + close(PARENT_ERROR_FD); - system(command); - exit(0); - } else { - close(CHILD_READ_FD); - close(CHILD_WRITE_FD); - close(CHILD_ERROR_FD); + system(command); + exit(0); + } else { + close(CHILD_READ_FD); + close(CHILD_WRITE_FD); + close(CHILD_ERROR_FD); - return stds{fdopen(PARENT_WRITE_FD, "w"), fdopen(PARENT_READ_FD, "r"), fdopen(PARENT_ERROR_FD, "r"), (pid_t) pid}; - } + return stds{fdopen(PARENT_WRITE_FD, "w"), fdopen(PARENT_READ_FD, "r"), fdopen(PARENT_ERROR_FD, "r"), (pid_t) pid}; + } } diff --git a/src/procopen.h b/src/procopen.h index 7edbc84..1ec622e 100644 --- a/src/procopen.h +++ b/src/procopen.h @@ -28,10 +28,10 @@ typedef struct { - FILE* stdin; - FILE* stdout; - FILE* stderr; - pid_t pid; + FILE* stdin; + FILE* stdout; + FILE* stderr; + pid_t pid; } stds;