diff --git a/src/client.cpp b/src/client.cpp index a540f34..b39daa1 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -224,11 +224,11 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col printf("STAGE 0\n"); flush(cout); - HttpConnection *req = nullptr; + HttpConnection req; printf("STAGE 1\n"); flush(cout); try { - *req = HttpConnection(socket); + req = HttpConnection(socket); } catch (char *msg) { try { if (msg == "Malformed header") { @@ -260,21 +260,21 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col thread *t; long pos; - if (req->isExistingField("Connection") && req->getField("Connection") == "keep-alive") { - req->setField("Connection", "keep-alive"); - req->setField("Keep-Alive", "timeout=3600, max=100"); + if (req.isExistingField("Connection") && req.getField("Connection") == "keep-alive") { + req.setField("Connection", "keep-alive"); + req.setField("Keep-Alive", "timeout=3600, max=100"); } else { - req->setField("Connection", "close"); + req.setField("Connection", "close"); error = true; } host = ""; - if (!req->isExistingField("Host")) { - req->respond(400); + if (!req.isExistingField("Host")) { + req.respond(400); goto respond; } - host = req->getField("Host"); + host = req.getField("Host"); pos = host.find(':'); if (pos != string::npos) { host.erase(pos, host.length() - pos); @@ -299,19 +299,19 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col 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); - noRedirect = req->getPath().find("/.well-known/") == 0 || (req->getPath().find("/files/") == 0); + noRedirect = req.getPath().find("/.well-known/") == 0 || (req.getPath().find("/files/") == 0); printf("STAGE 4\n"); flush(cout); redir = true; if (!noRedirect) { if (getWebRoot(host).empty()) { - req->redirect(303, "https://www.necronda.net" + req->getPath()); + req.redirect(303, "https://www.necronda.net" + req.getPath()); } else if (socket->getSocketPort() != 443) { - req->redirect(302, "https://" + host + req->getPath()); + req.redirect(302, "https://" + host + req.getPath()); } else { redir = false; } @@ -319,60 +319,60 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col redir = false; } - *path = URI(getWebRoot(host), req->getPath()); + *path = URI(getWebRoot(host), req.getPath()); childpid = 0; printf("STAGE 5\n"); flush(cout); if (redir) { goto respond; - } else if (!path->getNewPath().empty() && req->getMethod() != "POST") { - req->redirect(303, path->getNewPath()); + } else if (!path->getNewPath().empty() && req.getMethod() != "POST") { + req.redirect(303, path->getNewPath()); goto respond; } file = path->openFile(); if (file == nullptr) { - req->setField("Cache-Control", "public, max-age=60"); - req->respond(404); + req.setField("Cache-Control", "public, max-age=60"); + req.respond(404); goto respond; } type = path->getFileType(); if (type.find("inode/") == 0 || (path->getRelativeFilePath().find("/.") != string::npos && !noRedirect)) { - req->respond(403); + req.respond(403); goto respond; } printf("STAGE 6\n"); flush(cout); - req->setField("Content-Type", type); - req->setField("Last-Modified", getHttpDate(path->getFilePath())); + req.setField("Content-Type", type); + req.setField("Last-Modified", getHttpDate(path->getFilePath())); invalidMethod = false; etag = false; if (path->isStatic()) { hash = getETag(path->getFilePath()); - req->setField("ETag", hash); - req->setField("Accept-Ranges", "bytes"); + req.setField("ETag", hash); + req.setField("Accept-Ranges", "bytes"); if (type.find("text/") == 0) { - req->setField("Cache-Control", "public, max-age=3600"); + req.setField("Cache-Control", "public, max-age=3600"); } else { - req->setField("Cache-Control", "public, max-age=86400"); + req.setField("Cache-Control", "public, max-age=86400"); } - req->setField("Allow", "GET"); - if (req->getMethod() != "GET") { + req.setField("Allow", "GET"); + if (req.getMethod() != "GET") { invalidMethod = true; } - if (req->isExistingField("If-None-Match") && req->getField("If-None-Match") == hash) { + 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") { + 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; } } @@ -380,10 +380,10 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col flush(cout); if (invalidMethod) { - req->respond(405); + req.respond(405); goto respond; } else if (etag) { - req->respond(304); + req.respond(304); goto respond; } @@ -392,13 +392,13 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col 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( + " " + 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")) : "") + + (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()) + @@ -406,8 +406,8 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col " 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()) + + " 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") + @@ -423,9 +423,9 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col 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); + 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); @@ -453,7 +453,7 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col } else if (index == "Content-Type") { type = data; } - req->setField(index, data); + req.setField(index, data); } } printf("STAGE 10\n"); @@ -463,7 +463,7 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col int c = fgetc(pipes.stdout); if (c == -1) { // No Data -> Error - req->respond((statuscode == 0) ? 500 : statuscode); + req.respond((statuscode == 0) ? 500 : statuscode); statuscode = -1; } else { ungetc(c, pipes.stdout); @@ -481,26 +481,26 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col (type.find("application/") == 0 && type.find("+xml") != string::npos) || type == "application/json" || type == "application/javascript") && - req->isExistingField("Accept-Encoding") && - req->getField("Accept-Encoding").find("deflate") != string::npos; + req.isExistingField("Accept-Encoding") && + req.getField("Accept-Encoding").find("deflate") != string::npos; if (compress) { - req->setField("Accept-Ranges", "none"); + req.setField("Accept-Ranges", "none"); } - if (compress && req->isExistingField("Range")) { - req->respond(416); - } else if (req->isExistingField("Range")) { - string range = req->getField("Range"); + 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); + 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); + req.respond(416); } else { string part1 = range.substr(6, (unsigned long) (p - 6)); string part2 = range.substr((unsigned long) (p + 1), @@ -511,18 +511,18 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col num2 = stol(part2, nullptr, 10); } if (num1 < 0 || num1 >= len || num2 < 0 || num2 >= len) { - req->respond(416); + req.respond(416); } else { - req->setField("Content-Range", + req.setField("Content-Range", (string) "bytes " + to_string(num1) + "-" + to_string(num2) + "/" + to_string(len)); - req->respond(206, file, compress, num1, num2); + req.respond(206, file, compress, num1, num2); } } } } else { - req->respond(statuscode, file, compress); + req.respond(statuscode, file, compress); } } @@ -538,7 +538,7 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col printf("STAGE RESPOND\n"); flush(cout); - HttpStatusCode status = req->getStatusCode(); + HttpStatusCode status = req.getStatusCode(); int code = status.code; string color = ""; string comment = ""; @@ -549,32 +549,32 @@ bool connection_handler(const char *preprefix, const char *col1, const char *col } else if (code >= 300 && code < 400) { color = "\x1B[1;93m"; // Redirect: Yellow comment = " -> " + - (req->isExistingResponseField("Location") ? req->getResponseField("Location") : ""); + (req.isExistingResponseField("Location") ? req.getResponseField("Location") : ""); } else if (code >= 400 && code < 500) { color = "\x1B[1;31m"; // Client Error: Red - //comment = " -> " + req->getPath(); + //comment = " -> " + req.getPath(); } else if (code >= 500 & code < 600) { color = "\x1B[1;31m"; // Server Error: Red - //comment = " -> " + req->getPath(); + //comment = " -> " + req.getPath(); } - string msg = color + to_string(status.code) + " " + status.message + comment + " (" + formatTime(req->getDuration()) + ")\x1B[0m"; + 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()) + ")"); + 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); + 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); + req.setField("Connection", "close"); + req.respond(400); } else { log(prefix, (string) "Unable to receive from socket: " + msg); error = true;