From f06cbabe021d621325462fc143e3602d8443a324 Mon Sep 17 00:00:00 2001 From: dantol29 Date: Wed, 22 May 2024 13:07:27 +0200 Subject: [PATCH 01/17] fix(CGI):: add Debug::log --- src/CGIHandler.cpp | 23 ++++++++--------------- src/events/EventManager.cpp | 12 ++++-------- src/events/ServerEventListener.cpp | 1 - 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/src/CGIHandler.cpp b/src/CGIHandler.cpp index f4e8d0f7..85b28a94 100644 --- a/src/CGIHandler.cpp +++ b/src/CGIHandler.cpp @@ -36,8 +36,7 @@ CGIHandler &CGIHandler::operator=(const CGIHandler &other) void CGIHandler::handleRequest(HTTPRequest &request, HTTPResponse &response) { - - std::cout << RED << "Entering CGIHandler::handleRequest" << RESET << std::endl; + Debug::log("CGIHandler::handleRequest", Debug::CGI); MetaVariables env; env.HTTPRequestToMetaVars(request, env); if (!executeCGI(env, response)) @@ -45,8 +44,7 @@ void CGIHandler::handleRequest(HTTPRequest &request, HTTPResponse &response) response.setStatusCode(500, ""); response.setBody("500 Internal Server Error"); } - std::cout << GREEN << _connection.getCGIPid() << RESET << std::endl; - std::cout << RED << "Exiting CGIHandler::handleRequest" << RESET << std::endl; + Debug::log("Connection PID" + toString(_connection.getCGIPid()), Debug::CGI); return; } @@ -54,11 +52,11 @@ std::vector CGIHandler::createArgvForExecve(const MetaVariables &en { std::vector argv; std::string scriptName = env.getVar("SCRIPT_NAME"); - std::cout << "createArgvForExecve: scriptName: " << scriptName << std::endl; + Debug::log("createArgvForExecve: scriptName: " + scriptName, Debug::CGI); std::string pathTranslated = env.getVar("PATH_TRANSLATED"); - std::cout << "createArgvForExecve: pathTranslated: " << pathTranslated << std::endl; + Debug::log("createArgvForExecve: pathTranslated: " + pathTranslated, Debug::CGI); std::string scriptPath = pathTranslated; - std::cout << "createArgvForExecve: scriptPath: " << scriptPath << std::endl; + Debug::log("createArgvForExecve: scriptPath: " + scriptPath, Debug::CGI); if (env.getVar("X_INTERPRETER_PATH") != "") { @@ -100,12 +98,12 @@ std::vector CGIHandler::convertToCStringArray(const std::vector argv = createArgvForExecve(env); std::vector envp = env.getForExecve(); @@ -160,15 +158,10 @@ bool CGIHandler::executeCGI(const MetaVariables &env, HTTPResponse &response) close(pipeFD[1]); EventData data = {1, pid}; // Assuming 1 is the event type for CGI started - std::cout << "CGIHandler: Emitting event indicating a CGI process has started" << std::endl; _eventManager.emit(data); // Emit event indicating a CGI process has started // conn.addCGI(pid); _connection.addCGI(pid); - std::cout << GREEN << _connection.getCGIPid() << RESET << std::endl; - // TODO: is this used? To which process to you want to send this signal/ @Leo - // signal(SIGALRM, handleTimeout); - // alarm(4); - std::cout << RED << "Exiting CGIHandler::executeCGI with true" << RESET << std::endl; + Debug::log("CGIHandler: CGI PID: " + toString(_connection.getCGIPid()), Debug::CGI); return true; } diff --git a/src/events/EventManager.cpp b/src/events/EventManager.cpp index 981ec6d7..bcbcd9a2 100644 --- a/src/events/EventManager.cpp +++ b/src/events/EventManager.cpp @@ -24,13 +24,9 @@ std::vector EventManager::getObservers() const // Subscribe an observer to this manager void EventManager::subscribe(IEventListener *observer) { - std::cout << YELLOW << "Subscribing observer" << RESET << std::endl; + Debug::log("EventManager::subscribe", Debug::EVENTS); _observers.push_back(observer); - for (std::vector::iterator it = _observers.begin(); it != _observers.end(); ++it) - { - std::cout << "Observer: " << *it << std::endl; - } - std::cout << "Size of observers: " << _observers.size() << std::endl; + Debug::log("Size of observers: " + toString(_observers.size()), Debug::EVENTS); } // Unsubscribe an observer from this manager @@ -45,9 +41,9 @@ void EventManager::unsubscribe(IEventListener *observer) // void EventManager::emit(int eventID) void EventManager::emit(const EventData &eventData) { - std::cout << YELLOW << "Event emitted: " << eventData << RESET << std::endl; + Debug::log("EventManager::emit", Debug::EVENTS); // Notify all observers about the event - std::cout << "Size of observers: " << _observers.size() << std::endl; + Debug::log("Size of observers: " + toString(_observers.size()), Debug::EVENTS); for (std::vector::iterator it = _observers.begin(); it != _observers.end(); ++it) { (*it)->handleEvent(eventData); diff --git a/src/events/ServerEventListener.cpp b/src/events/ServerEventListener.cpp index 38a2722d..01c788cf 100644 --- a/src/events/ServerEventListener.cpp +++ b/src/events/ServerEventListener.cpp @@ -7,7 +7,6 @@ ServerEventListener::ServerEventListener(Server &srv) : server(srv) void ServerEventListener::handleEvent(const EventData &eventData) { - std::cout << "ServerEventListener::handleEvent: " << eventData << std::endl; // TODO; Create eventually enum for eventID if (eventData.eventType == 1) server.addCGI(eventData); From 83787bbdd2c08b7b38601489d2668eb7750174e9 Mon Sep 17 00:00:00 2001 From: dantol29 Date: Wed, 22 May 2024 13:17:48 +0200 Subject: [PATCH 02/17] fix(logger): add more prints --- src/Connection.cpp | 35 +++++++++++++---------------------- src/HTTPRequest.cpp | 2 +- src/HTTPResponse.cpp | 13 +++++-------- src/Listen.cpp | 2 +- src/MetaVariables.cpp | 7 ++++--- src/Parser.cpp | 7 +------ 6 files changed, 25 insertions(+), 41 deletions(-) diff --git a/src/Connection.cpp b/src/Connection.cpp index e657ef10..28caa1f7 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -56,7 +56,7 @@ Connection::Connection(const Connection &other) _CGIExitStatus = other._CGIExitStatus; _CGIHasCompleted = other._CGIHasCompleted; _CGIHasTimedOut = other._CGIHasTimedOut; - // std::cout << "Connection object copied" << std::endl; + Debug::log("Connection object copied", Debug::OCF); } Connection &Connection::operator=(const Connection &other) @@ -88,13 +88,13 @@ Connection &Connection::operator=(const Connection &other) _CGIHasCompleted = other._CGIHasCompleted; _CGIHasTimedOut = other._CGIHasTimedOut; } - std::cout << "Connection object assigned" << std::endl; + Debug::log("Connection object assigned", Debug::OCF); return *this; } Connection::~Connection() { - // std::cout << "Connection object destroyed" << std::endl; + Debug::log("Connection object destroyed", Debug::OCF); } // GETTERS AND SETTERS @@ -314,18 +314,14 @@ void Connection::setCGIExitStatus(int status) bool Connection::readHeaders(Parser &parser) { - // std::cout << "\nEntering readHeaders" << std::endl; const int bufferSize = BUFFER_SIZE; char buffer[bufferSize] = {0}; - std::cout << "buffers size: " << sizeof(buffer) << std::endl; + Debug::log("buffer size: " + toString(sizeof(buffer)), Debug::SERVER); ssize_t bytesRead = recv(_pollFd.fd, buffer, bufferSize, 0); - std::cout << "bytesRead: " << bytesRead << std::endl; + Debug::log("bytesRead: " + toString(bytesRead), Debug::SERVER); if (bytesRead > 0) { parser.setBuffer(parser.getBuffer() + std::string(buffer, bytesRead)); - // std::cout << "The buffer is: " << parser.getBuffer() << std::endl; - - // std::cout << "Exiting readHeaders" << std::endl; return true; } else if (bytesRead < 0) @@ -335,12 +331,12 @@ bool Connection::readHeaders(Parser &parser) } else if (bytesRead == 0) { - std::cout << "Connection closed before headers being completely sent" << std::endl; + Debug::log("Connection closed before headers being completely sent", Debug::SERVER); return false; } else { - std::cout << "Exiting readHeaders. This will never happen here!" << std::endl; + Debug::log("Exiting readHeaders. This will never happen here!", Debug::SERVER); return true; } } @@ -412,7 +408,7 @@ bool Connection::readChunkSize(std::string &line) } else { - std::cout << "Connection closed" << std::endl; + Debug::log("Connection closed while reading chunk size", Debug::SERVER); return false; } } @@ -459,24 +455,20 @@ bool Connection::readChunk(size_t chunkSize, std::string &chunkData, HTTPRespons bool Connection::readBody(Parser &parser, HTTPRequest &req, HTTPResponse &res) { - std::cout << "\nEntering readBody" << std::endl; size_t contentLength = req.getContentLength(); char buffer[BUFFER_SIZE]; // We could also use _bodyTotalBytesRead from the parser size_t bytesRead = parser.getBuffer().size(); - std::cout << "contentLength: " << contentLength << std::endl; - std::cout << "bytesRead: " << bytesRead << std::endl; + Debug::log("contentLength: " + toString(contentLength), Debug::SERVER); + Debug::log("bytesRead: " + toString(bytesRead), Debug::SERVER); if (bytesRead < contentLength) { ssize_t read = recv(_pollFd.fd, buffer, BUFFER_SIZE, 0); if (read > 0) { - std::cout << "read > 0" << std::endl; - // _body.append(buffer, read);j parser.setBuffer(parser.getBuffer() + std::string(buffer, read)); - std::cout << "bytesRead: " << parser.getBuffer().size() << std::endl; - // std::cout << "The 'body; is: " << parser.getBuffer() << std::endl; + Debug::log("bytesRead: " + toString(parser.getBuffer().size()), Debug::SERVER); bytesRead += read; if (bytesRead == contentLength) { @@ -492,14 +484,13 @@ bool Connection::readBody(Parser &parser, HTTPRequest &req, HTTPResponse &res) } else { - std::cout << "read == 0" << std::endl; + Debug::log("read == 0", Debug::SERVER); res.setStatusCode(499, "Connection closed by the client"); // Client Closed Request return false; } } else parser.setBodyComplete(true); - std::cout << "Exiting readBody" << std::endl; return true; } @@ -508,7 +499,7 @@ void Connection::addCGI(pid_t pid) { _hasCGI = true; _CGIPid = pid; - std::cout << "CGI process added with pid: " << _CGIPid << std::endl; + Debug::log("CGI process added with pid: " + toString(_CGIPid), Debug::CGI); _CGIStartTime = time(NULL); } diff --git a/src/HTTPRequest.cpp b/src/HTTPRequest.cpp index 2474404b..9205b9ad 100644 --- a/src/HTTPRequest.cpp +++ b/src/HTTPRequest.cpp @@ -194,7 +194,7 @@ void HTTPRequest::replaceHeader(const std::string &key, const std::string &value std::string lowerKey = key; for (size_t i = 0; i < lowerKey.size(); ++i) lowerKey[i] = std::tolower(static_cast(lowerKey[i])); - std::cout << "Replacing header: " << key << " with value: " << lowerKey << std::endl; + Debug::log("Replacing header: " + key + " with value: " + lowerKey, Debug::PARSER); std::multimap::iterator it = _headers.find(lowerKey); if (it != _headers.end()) _headers.erase(it); diff --git a/src/HTTPResponse.cpp b/src/HTTPResponse.cpp index 58f5a8cf..96c3fc93 100644 --- a/src/HTTPResponse.cpp +++ b/src/HTTPResponse.cpp @@ -14,16 +14,14 @@ void HTTPResponse::setErrorResponse(int statusCode) { std::string statusMessage = getStatusMessage(statusCode); std::string code = toString(statusCode); - std::cout << "\033[31m" - << "Error " << statusCode << " in request" - << "\033[0m" << std::endl; + Debug::log("statusCode: " + code + " statusMessage: " + statusMessage, Debug::NORMAL); std::string body = "Error" "

Error: " + code + " " + "

" + statusMessage + "

"; - // print purple to identify a 0 status code - std::cout << PURPLE << "setErrorResponse: statusCode: " << statusCode << " statusMessage: " << statusMessage - << " body: " << body << RESET << std::endl; + Debug::log("setErrorResponse: statusCode: " + code + " statusMessage: " + statusMessage + + " body: " + body, + Debug::NORMAL); setStatusCode(statusCode, ""); setHeader("Content-Length", toString(body.length())); setHeader("Content-Type", "text/html"); @@ -146,7 +144,7 @@ void HTTPResponse::CGIStringToResponse(const std::string &cgiOutput) std::string headersPart = cgiOutput.substr(0, headerEndPos); std::string bodyPart = cgiOutput.substr(headerEndPos); - std::cout << "------------------CGIStringToResponse-------------------" << std::endl; + Debug::log("------------------CGIStringToResponse-------------------", Debug::CGI); std::istringstream headerStream(headersPart); std::string headerLine; @@ -318,7 +316,6 @@ const std::string &HTTPResponse::getStatusMessage() const std::ostream &operator<<(std::ostream &out, const HTTPResponse &response) { - std::cout << "HTTPResponse operator<< called" << std::endl; // Output the status out << "\033[35m"; out << "Status Code: " << response.getStatusCode() << "\n"; diff --git a/src/Listen.cpp b/src/Listen.cpp index 3603bf1c..bffa4d07 100644 --- a/src/Listen.cpp +++ b/src/Listen.cpp @@ -42,7 +42,7 @@ Listen::Listen(std::string str) std::cerr << "Throwing exception" << std::endl; throw("Invalid ip or port"); } - std::cout << "Listen object created. IP: " << _ip << ", Port: " << _port << std::endl; + Debug::log("Listen object created. IP: " + _ip + ", Port: " + toString(_port), Debug::OCF); } Listen::Listen(const Listen &obj) diff --git a/src/MetaVariables.cpp b/src/MetaVariables.cpp index a927f169..45782004 100644 --- a/src/MetaVariables.cpp +++ b/src/MetaVariables.cpp @@ -154,10 +154,11 @@ void MetaVariables::HTTPRequestToMetaVars(const HTTPRequest &request, MetaVariab std::string queryString = formatQueryString(request.getQueryString()); env.setVar("QUERY_STRING", queryString); - std::cout << "MetaVariables::HTTPRequestToMetaVars: request.getRequestTarget(): " << request.getRequestTarget() - << std::endl; + Debug::log("MetaVariables::HTTPRequestToMetaVars: request.getRequestTarget(): " + request.getRequestTarget(), + Debug::CGI); + std::pair pathComponents = separatePathAndInfo(request.getRequestTarget()); - std::cout << "MetaVariables::HTTPRequestToMetaVars: pathComponents.first: " << pathComponents.first << std::endl; + Debug::log("MetaVariables::HTTPRequestToMetaVars: pathComponents.second: " + pathComponents.second, Debug::CGI); std::string root = request.getRoot(); std::string host = request.getSingleHeader("host").second; diff --git a/src/Parser.cpp b/src/Parser.cpp index 1868604c..1652b1b5 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -21,19 +21,15 @@ Parser::~Parser() bool Parser::preParseHeaders(HTTPResponse &res) { - // We read the buffer with readHeaders if headersComplete is not true and we write the buffer in the _headersBuffer std::size_t headersEnd = _buffer.find("\r\n\r\n"); if (headersEnd != std::string::npos) { _headersBuffer = _buffer.substr(0, headersEnd + 4); _headersComplete = true; _buffer = _buffer.substr(headersEnd + 4); - // std::cout << _buffer << std::endl; - // std::cout << "\033[31m" - // << "_buffer size " << _buffer.size() << "\033[0m" << std::endl; return (true); } - std::cout << "headers are not complete" << std::endl; + Debug::log("headers are not complete", Debug::PARSER); if (_buffer.length() > CLIENT_MAX_HEADERS_SIZE) return (res.setStatusCode(431, "Headers too large"), false); return true; @@ -309,7 +305,6 @@ void Parser::saveCokies(HTTPRequest &req) i++; value = cookie.substr(start, i - start); req.setCookies(key, value); - std::cout << cookie.substr(i) << std::endl; if (cookie[i] == ';') start = ++i; } From c8c28c52c570c3d9f8dee501a506c3b86456c705 Mon Sep 17 00:00:00 2001 From: dantol29 Date: Wed, 22 May 2024 13:26:10 +0200 Subject: [PATCH 03/17] fix(logger): remove std::couts form Router --- src/Router.cpp | 46 +++++++++++++++++----------------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/src/Router.cpp b/src/Router.cpp index bead8656..bc36183e 100644 --- a/src/Router.cpp +++ b/src/Router.cpp @@ -63,19 +63,14 @@ void Router::routeRequest(HTTPRequest &request, HTTPResponse &response) if (root.empty()) root = "var/"; request.setRoot(root); - std::string path = root + request.getSingleHeader("host").second; - std::string requestTarget = request.getRequestTarget(); - std::cout << YELLOW << "requestTarget: " << requestTarget << RESET << std::endl; adaptPathForFirefox(request); - - std::cout << GREEN << "Routing request to path: " << request.getPath() << RESET << std::endl; - - // std::cout << request << std::endl; + + Debug::log("Routing Request: path = " + request.getPath(), Debug::NORMAL); PathValidation pathResult = pathIsValid(response, request); - std::cout << BLUE << "path: " << request.getPath() << RESET << std::endl; - std::cout << BLUE << "PathValidation: " << pathResult << RESET << std::endl; + Debug::log("Routing Request: pathResult = " + std::to_string(pathResult), Debug::NORMAL); + Debug::log("Path requested: " + request.getPath(), Debug::NORMAL); // check if method is allowed if (!_directive._allowedMethods.empty()) @@ -104,8 +99,7 @@ void Router::routeRequest(HTTPRequest &request, HTTPResponse &response) cgiHandler.setFDsRef(_FDsRef); cgiHandler.setPollFd(_pollFd); cgiHandler.handleRequest(request, response); - std::cout << GREEN << _connection.getCGIPid() << RESET << std::endl; - std::cout << "CGI request handled" << std::endl; + Debug::log("CGI request handled", Debug::CGI); } else if (request.getMethod() == "POST" || request.getUploadBoundary() != "") { @@ -120,15 +114,13 @@ void Router::routeRequest(HTTPRequest &request, HTTPResponse &response) } break; case IsDirectoryListing: - std::cout << "Path is a directory listing, generating directory listing" << std::endl; generateDirectoryListing(response, request.getPath(), request.getRequestTarget()); break; case PathInvalid: - std::cout << "Path is not valid, handling as error" << std::endl; handleServerBlockError(request, response, 404); return; } - std::cout << "Before SALAD method check" << std::endl; + if (request.getMethod() == "SALAD") { std::cout << "🥬 + 🍅 + 🐟 = 🥗" << std::endl; @@ -178,7 +170,6 @@ void Router::handleServerBlockError(HTTPRequest &request, HTTPResponse &response { if (errorPage[i].first == errorCode) { - std::cout << "handleServerBlockError: Error code: " << errorCode << std::endl; Debug::log("Path requested: " + request.getPath(), Debug::NORMAL); Debug::log("Path to error: " + errorPage[i].second, Debug::NORMAL); // setting the path to the custom error page @@ -228,24 +219,22 @@ bool Router::requestIsCGI(const HTTPRequest &request) // TODO: check against config file, not this hardcoded version std::vector cgiExtensions = _directive._cgiExt; - std::cout << RED << "requestIsCGI" << RESET << std::endl; - std::cout << "cgiExtensions: " << cgiExtensions.size() << std::endl; - std::cout << "request target: " << request.getRequestTarget() << std::endl; + Debug::log("cgiExtensions: " + toString(cgiExtensions.size()), Debug::CGI); if (!cgiExtensions.empty()) { std::string fileExtension = getFileExtension(request.getRequestTarget()); - std::cout << "fileExtension: " << fileExtension << std::endl; + Debug::log("fileExtension: " + fileExtension, Debug::CGI); for (size_t i = 0; i < cgiExtensions.size(); i++) { - std::cout << "cgiExtensions[" << i << "]: " << cgiExtensions[i] << std::endl; + Debug::log("cgiExtensions[" + toString(i) + "]: " + cgiExtensions[i], Debug::CGI); if (cgiExtensions[i] == fileExtension) { - Debug::log("requestIsCGI: CGI request detected", Debug::NORMAL); + Debug::log("requestIsCGI: CGI request detected", Debug::CGI); return true; } } } - Debug::log("requestIsCGI: Not a CGI request", Debug::NORMAL); + Debug::log("requestIsCGI: Not a CGI request", Debug::CGI); return false; } @@ -334,13 +323,12 @@ enum PathValidation Router::pathIsValid(HTTPResponse &response, HTTPRequest &req if (!isDirectory(path) && stat(path.c_str(), &buffer) == 0) { Debug::log("pathIsValid: stat success", Debug::NORMAL); - std::cout << " path :" << path << std::endl; + Debug::log("pathIsValid: " + path, Debug::NORMAL); return PathValid; } else if (!isDirectory(path) && stat(path.c_str(), &buffer) != 0) { - std::cout << "Failed to stat the file at path: " << path << std::endl; - Debug::log("pathIsValid: stat failed, path does not exist", Debug::NORMAL); + Debug::log("pathIsValid: stat failed: " + path, Debug::NORMAL); return PathInvalid; } @@ -355,13 +343,13 @@ enum PathValidation Router::pathIsValid(HTTPResponse &response, HTTPRequest &req std::string index = _directive._index[i]; std::string tmpPath = request.getPath(); tmpPath = tmpPath + "/" + index; - std::cout << "tmpPath: " << tmpPath << std::endl; + Debug::log("user error path: " + tmpPath, Debug::NORMAL); if (stat(tmpPath.c_str(), &buffer) == 0) { if (tmpPath.find("//") != std::string::npos) tmpPath.replace(tmpPath.find("//"), 2, "/"); - std::cout << "tmpPath: " << tmpPath << std::endl; + Debug::log("user error path: " + tmpPath, Debug::NORMAL); Debug::log("pathIsValid: using index from user: " + index, Debug::NORMAL); request.setPath(tmpPath); return PathValid; @@ -372,7 +360,7 @@ enum PathValidation Router::pathIsValid(HTTPResponse &response, HTTPRequest &req if (!path.empty()) { path += "/index.html"; // append /index.html - std::cout << "path: " << path << std::endl; + Debug::log("pathIsValid: " + path, Debug::NORMAL); if (stat(path.c_str(), &buffer) == 0) { Debug::log("pathIsValid: using default index.html", Debug::NORMAL); @@ -385,7 +373,7 @@ enum PathValidation Router::pathIsValid(HTTPResponse &response, HTTPRequest &req { Debug::log("pathIsValid: Autoindex is on", Debug::NORMAL); generateDirectoryListing(response, path, request.getRequestTarget()); - std::cout << "Directory listing generated for " << path << std::endl; + Debug::log("pathIsValid: generated directory listing for " + path, Debug::NORMAL); return IsDirectoryListing; } Debug::log("pathIsValid: invalid path", Debug::NORMAL); From de358444aff4970d549339b176c7ba010ecf6e3c Mon Sep 17 00:00:00 2001 From: dantol29 Date: Wed, 22 May 2024 13:49:59 +0200 Subject: [PATCH 04/17] fix(Sever): add std::cout to logger --- src/Server.cpp | 120 +++++++++++++++-------------------- src/ServerSocket.cpp | 20 ++---- src/StaticContentHandler.cpp | 10 +-- src/UploadHandler.cpp | 33 ++++------ 4 files changed, 75 insertions(+), 108 deletions(-) diff --git a/src/Server.cpp b/src/Server.cpp index e4bc5c84..de34d95d 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -72,9 +72,9 @@ void Server::startPollEventLoop() timeout = 1000; // 1 seconds else timeout = -1; - printConnections("BEFORE POLL", _FDs, _connections, true); - std::cout << CYAN << "++++++++++++++ #" << pollCounter - << " Waiting for new connection or Polling +++++++++++++++" << RESET << std::endl; + //printConnections("BEFORE POLL", _FDs, _connections, true); + Debug::log(toString(CYAN) + "++++++++++++++ #" + toString(pollCounter) + \ + " Waiting for new connection or Polling +++++++++++++++" + toString(RESET), Debug::SERVER); int ret = poll(_FDs.data(), _FDs.size(), timeout); pollCounter++; // printFrame("POLL EVENT DETECTED", true); @@ -110,7 +110,6 @@ void Server::startPollEventLoop() else handlePollError(); - std::cout << "Has CGI: " << (_hasCGI ? "true" : "false") << std::endl; if (_hasCGI) waitCGI(); } @@ -122,10 +121,11 @@ void Server::waitCGI() size_t originalSize = _FDs.size(); int status; pid_t pid = waitpid(-1, &status, WNOHANG); - std::cout << "PID: " << pid << std::endl; + Debug::log("PID: " + toString(pid), Debug::CGI); for (size_t i = 0; i < originalSize && i < _FDs.size(); i++) - std::cout << _connections[i].getCGIPid() << ", " << _connections[i].getHasCGI() << std::endl; + Debug::log("PID: " + toString(_connections[i].getCGIPid() + ", hasCGI: " + \ + toString(_connections[i].getHasCGI())), Debug::CGI); if (pid > 0) { @@ -149,7 +149,7 @@ void Server::waitCGI() for (size_t i = 0; i < originalSize && i < _FDs.size(); i++) { double elapsed = difftime(time(NULL), _connections[i].getCGIStartTime()); - std::cout << RED << "Elapsed time: " << elapsed << " seconds" << RESET << std::endl; + Debug::log("Elapsed time: " + toString(elapsed) + " seconds", Debug::CGI); if (_connections[i].getHasCGI() && elapsed > 1) { Debug::log("CGI timed out", Debug::NORMAL); @@ -196,7 +196,7 @@ void Server::readFromClient(Connection &conn, size_t &i, Parser &parser, HTTPReq if (!parser.preParseHeaders(response)) { conn.setHasFinishedReading(true); - std::cout << "Error pre-parsing headers" << std::endl; + Debug::log("Error pre-parsing headers", Debug::SERVER); return; } } @@ -295,7 +295,7 @@ void Server::buildResponse(Connection &conn, size_t &i, HTTPRequest &request, HT { if (conn.getCGIHasTimedOut()) { - std::cout << "CGI timed out" << std::endl; + Debug::log("CGI timed out", Debug::CGI); response.setStatusCode(500, "Internal Server Error"); response.setIsCGI(false); } @@ -306,15 +306,15 @@ void Server::buildResponse(Connection &conn, size_t &i, HTTPRequest &request, HT ServerBlock serverBlock; Directives directive; - std::cout << GREEN << "Number of server blocks: " << _config.getServerBlocks().size() << RESET << std::endl; - std::cout << "Request host: " << request.getSingleHeader("host").second << std::endl; + Debug::log("Number of server blocks: " + toString(_config.getServerBlocks().size()), Debug::SERVER); + Debug::log("Request host: " + request.getSingleHeader("host").second, Debug::SERVER); formRequestTarget(request); if (conn.getHasServerBlock() != NOT_FOUND) findLocationBlock(request, conn.getServerBlock(), directive); - std::cout << RED << "Root: " << directive._root << RESET << std::endl; + Debug::log("Root: " + directive._root, Debug::SERVER); Router router(directive, _eventManager, conn); @@ -334,12 +334,10 @@ void Server::buildResponse(Connection &conn, size_t &i, HTTPRequest &request, HT router.setFDsRef(&_FDs); router.setPollFd(&conn.getPollFd()); router.routeRequest(request, response); - std::cout << GREEN << conn.getCGIPid() << RESET << std::endl; } - std::cout << "Is Response CGI? " << response.getIsCGI() << std::endl; + if (!response.getIsCGI()) { - std::cout << "Setting setHasDataToSend to true" << std::endl; conn.setHasDataToSend(true); return; } @@ -347,40 +345,39 @@ void Server::buildResponse(Connection &conn, size_t &i, HTTPRequest &request, HT void Server::buildCGIResponse(Connection &conn, HTTPResponse &response) { - std::cout << RED << "Entering buildCGIResponse" << RESET << std::endl; + Debug::log("Entering buildCGIResponse", Debug::CGI); std::string cgiOutput; int *pipeFD; pipeFD = response.getCGIpipeFD(); char readBuffer[256]; // TODO: this is blokcing - we need to make it non-blocking // I.e. read 1 buffer and then go back to poll - std::cout << "Reading from pipe" << std::endl; + Debug::log("Reading from pipe", Debug::CGI); ssize_t bytesRead; do { - std::cout << "Into the do while loop" << std::endl; bytesRead = read(pipeFD[0], readBuffer, sizeof(readBuffer) - 1); - std::cout << "Bytes read: " << bytesRead << std::endl; + Debug::log("Bytes read: " + toString(bytesRead), Debug::CGI); if (bytesRead > 0) { - std::cout << "Bytes read: " << bytesRead << std::endl; + Debug::log("Bytes read: " + toString(bytesRead), Debug::CGI); readBuffer[bytesRead] = '\0'; cgiOutput += readBuffer; } else if (bytesRead == 0) { - std::cout << "End of data stream reached." << std::endl; + Debug::log("End of data stream reached", Debug::CGI); break; // Optional: Explicitly break if you need to perform additional cleanup. } else { - std::cerr << "Error reading data: " << strerror(errno) << std::endl; + Debug::log("Error reading data", Debug::CGI); break; // Break or handle the error as needed. } } while (bytesRead > 0); - std::cout << "CGI output: " << cgiOutput << std::endl; + Debug::log("CGI output: " + cgiOutput, Debug::CGI); close(pipeFD[0]); int status = conn.getCGIExitStatus(); @@ -416,8 +413,9 @@ void Server::buildCGIResponse(Connection &conn, HTTPResponse &response) void Server::writeToClient(Connection &conn, size_t &i, HTTPResponse &response) { - std::cout << "\033[1;36m" << "Entering writeToClient" << "\033[0m" << std::endl; - std::cout << response << std::endl; + Debug::log("Entering writeToClient", Debug::NORMAL); + Debug::log("response: " + response.objToString(), Debug::NORMAL); + static int sendResponseCounter = 0; bool isLastSend = false; size_t tmpBufferSize = SEND_BUFFER_SIZE; @@ -433,11 +431,11 @@ void Server::writeToClient(Connection &conn, size_t &i, HTTPResponse &response) if (conn.getResponseString().size() < SEND_BUFFER_SIZE) { tmpBufferSize = conn.getResponseString().size(); - std::cout << GREEN << "Sending last part of the response" << RESET << std::endl; + Debug::log("Sending last part of the response", Debug::NORMAL); isLastSend = true; } - std::cout << GREEN << "sendResponseCounter: " << sendResponseCounter << RESET << std::endl; + Debug::log("sendResponseCounter: " + toString(sendResponseCounter), Debug::NORMAL); int read = send(conn.getPollFd().fd, conn.getResponseString().c_str(), tmpBufferSize, 0); if (read == -1) { @@ -458,7 +456,7 @@ void Server::writeToClient(Connection &conn, size_t &i, HTTPResponse &response) void Server::closeClientConnection(Connection &conn, size_t &i) { - std::cout << "\033[1;36m" << "Entering closeClientConnection" << "\033[0m" << std::endl; + Debug::log("Entering closeClientConnection", Debug::NORMAL); // TODO: should we close it with the Destructor of the Connection class? close(conn.getPollFd().fd); _FDs.erase(_FDs.begin() + i); @@ -473,31 +471,23 @@ void Server::handleConnection(Connection &conn, size_t &i) HTTPResponse &response = _connections[i].getResponse(); // printFrame("CLIENT SOCKET EVENT", true); - std::cout << "\033[1;36m" << "Entering handleConnection" << "\033[0m" << std::endl; + Debug::log("Entering handleConnection", Debug::NORMAL); conn.setHasReadSocket(false); - std::cout << "Has finished reading: " << conn.getHasFinishedReading() << std::endl; if (!conn.getHasFinishedReading()) readFromClient(conn, i, parser, request, response); if (conn.getHasReadSocket() && !conn.getHasFinishedReading()) - { - std::cout << "Has read socket: " << conn.getHasReadSocket() << std::endl; return; - } - std::cout << request << std::endl; if (!conn.getCanBeClosed() && !conn.getHasDataToSend()) buildResponse(conn, i, request, response); // MInd that after the last read from the pipe of the CGI getHasReadSocket will be false but we will have a read // operation on the pipe, if we want to write just after going through poll we need an extra flag or something. - std::cout << "Has read socket: " << conn.getHasReadSocket() << std::endl; - std::cout << "Has data to send: " << conn.getHasDataToSend() << std::endl; if (conn.getHasDataToSend() && !conn.getHasReadSocket()) writeToClient(conn, i, response); - std::cout << "Can be closed: " << conn.getCanBeClosed() << std::endl; + if (conn.getCanBeClosed()) closeClientConnection(conn, i); - std::cout << RED << "Exiting handleConnection" << RESET << std::endl; } /*** Private Methods ***/ @@ -520,7 +510,7 @@ std::string normalizeIPAddress(const std::string &ip, bool isIpV6) void Server::createServerSockets(std::vector &serverBlocks) { - std::cout << BLUE << "Entering createServerSockets" << RESET << std::endl; + Debug::log("Entering createServerSockets", Debug::SERVER); std::vector allListens; for (std::vector::iterator it = serverBlocks.begin(); it != serverBlocks.end(); ++it) { @@ -576,8 +566,7 @@ void Server::createServerSockets(std::vector &serverBlocks) ServerSocket serverSocket(serverFD, *it); _serverSockets.push_back(serverSocket); } - std::cout << BLUE << "Server socket(s) created" << RESET << std::endl; - std::cout << "\n\n"; + Debug::log("Exiting createServerSockets", Debug::SERVER); } void Server::setReuseAddrAndPort() @@ -607,8 +596,8 @@ void Server::bindToPort() inet_ntop(AF_INET6, &(serverSocketAddr.sin6_addr), ipv6Address, INET6_ADDRSTRLEN); // Print original IP Address and Port - std::cout << "Original IP Address: " << ipv6Address << std::endl; - std::cout << "Original Port: " << ntohs(serverSocketAddr.sin6_port) << std::endl; + Debug::log("Original IP Address: " + std::string(ipv6Address), Debug::SERVER); + Debug::log("Original Port: " + toString(ntohs(serverSocketAddr.sin6_port)), Debug::SERVER); // Overwrite the IP address and port with hardcoded values for test // serverSocketAddr.sin6_addr = in6addr_any; // Bind to all interfaces for IPv6 @@ -619,17 +608,17 @@ void Server::bindToPort() // Print the sockaddr and address family // We reuse the ipv6Address buffer to store the new IP address inet_ntop(AF_INET6, &(serverSocketAddr.sin6_addr), ipv6Address, INET6_ADDRSTRLEN); - std::cout << "First print of serverSocketAddr" << std::endl; - std::cout << "IP Address: " << ipv6Address << std::endl; - std::cout << "Port: " << ntohs(serverSocketAddr.sin6_port) << std::endl; - std::cout << "Address Family: " << serverSocketAddr.sin6_family << std::endl; + // std::cout << "First print of serverSocketAddr" << std::endl; + // std::cout << "IP Address: " << ipv6Address << std::endl; + // std::cout << "Port: " << ntohs(serverSocketAddr.sin6_port) << std::endl; + // std::cout << "Address Family: " << serverSocketAddr.sin6_family << std::endl; int bindResult = bind(it->getServerFD(), serverSocketAddrPtr, sizeof(serverSocketAddr)); - std::cout << "Bind result: " << bindResult << std::endl; + Debug::log("Bind result: " + toString(bindResult), Debug::SERVER); if (bindResult < 0) { - std::cout << YELLOW << "Server socket failed to bind to IP " << ipv6Address << " on port " - << ntohs(serverSocketAddr.sin6_port) << RESET << std::endl; + Debug::log("Server socket failed to bind to IP " + std::string(ipv6Address) + " on port " + \ + toString(ntohs(serverSocketAddr.sin6_port)), Debug::SERVER); perror("In bind"); continue; // just to remember that we aren not exiting } @@ -639,14 +628,13 @@ void Server::bindToPort() char ipv6AddressBound[INET6_ADDRSTRLEN]; if (inet_ntop(AF_INET6, &(serverSocketAddr.sin6_addr), ipv6AddressBound, INET6_ADDRSTRLEN)) { - std::cout << YELLOW << "Server socket bound to IP " << ipv6AddressBound << " on port " - << ntohs(serverSocketAddr.sin6_port) << RESET << std::endl; + Debug::log("Server socket bound to IP " + std::string(ipv6AddressBound) + " on port " + \ + toString(ntohs(serverSocketAddr.sin6_port)), Debug::SERVER); } else { std::cerr << "Error converting bound IPv6 address to text." << std::endl; } - std::cout << "***" << std::endl; } // if (bind(it->getServerFD(), serverSocketAddrPtr, sizeof(serverSocketAddr)) < 0) } @@ -669,8 +657,8 @@ void Server::listen() // Convert IPv6 address from binary to text if (inet_ntop(AF_INET6, &addr.sin6_addr, ipv6Address, INET6_ADDRSTRLEN)) { - std::cout << "Server socket listening on IP " << ipv6Address << " and port " << ntohs(addr.sin6_port) - << std::endl; + Debug::log("Server socket listening on IP " + std::string(ipv6Address) + \ + " and port " + toString(ntohs(addr.sin6_port)), Debug::SERVER); } else { @@ -751,9 +739,7 @@ void Server::acceptNewConnection(Connection &conn) } /* start together */ _FDs.push_back(newSocketPoll); - _connections.push_back(newConnection); - std::cout << newConnection.getHasFinishedReading() << std::endl; - std::cout << _connections.back().getHasFinishedReading() << std::endl; + _connections.push_back(newConnection);; /* end together */ if (VERBOSE) { @@ -773,13 +759,13 @@ void Server::acceptNewConnection(Connection &conn) struct sockaddr_in *s = (struct sockaddr_in *)&clientAddress; // TODO: inet_ntop is forbidden in the subject. inet_ntop(AF_INET, &s->sin_addr, clientIP, sizeof clientIP); - std::cout << "New connection from (IPv4): " << clientIP << std::endl; + Debug::log("New connection from (IPv4): " + std::string(clientIP), Debug::SERVER); } else if (clientAddress.ss_family == AF_INET6) { struct sockaddr_in6 *s = (struct sockaddr_in6 *)&clientAddress; inet_ntop(AF_INET6, &s->sin6_addr, clientIP, sizeof clientIP); - std::cout << "New connection from (IPv6): " << clientIP << std::endl; + Debug::log("New connection from (IPv6): " + std::string(clientIP), Debug::SERVER); } else { @@ -799,7 +785,7 @@ void Server::handleServerSocketError() perror("poll server socket error"); if (errorCounter > 5) { - std::cerr << "Too many errors on server socket. Exiting." << std::endl; + Debug::log("Too many errors on server socket. Exiting.", Debug::SERVER); exit(EXIT_FAILURE); } ++errorCounter; @@ -807,7 +793,7 @@ void Server::handleServerSocketError() void Server::handleClientSocketError(int clientFD, size_t &i) { - std::cout << "handleClientSocketError" << std::endl; + Debug::log("Entering handleClientSocketError", Debug::SERVER); close(clientFD); /* start together */ _FDs.erase(_FDs.begin() + i); @@ -820,7 +806,7 @@ void Server::handleClientSocketError(int clientFD, size_t &i) void Server::handleSocketTimeoutIfAny() { // Is not the socket timeout, but the poll timeout - std::cout << "Timeout occurred!" << std::endl; + Debug::log("Timeout occurred", Debug::SERVER); // This should never happen with an infinite timeout } @@ -895,7 +881,6 @@ void Server::addCGI(const EventData &eventData) (void)eventData; setHasCGI(true); setCGICounter(getCGICounter() + 1); - std::cout << "CGI added: _hasCGI set to " << _hasCGI << ", _CGICounter is now " << _CGICounter << std::endl; } void Server::removeCGI() @@ -931,7 +916,7 @@ void Server::formRequestTarget(HTTPRequest &request) requestTarget = "/"; request.setRequestTarget(requestTarget); - std::cout << "Request target: " << request.getRequestTarget() << std::endl; + Debug::log("Request target: " + request.getRequestTarget(), Debug::SERVER); } void Server::findLocationBlock(HTTPRequest &request, ServerBlock &serverBlock, Directives &directive) @@ -940,11 +925,10 @@ void Server::findLocationBlock(HTTPRequest &request, ServerBlock &serverBlock, D for (size_t i = 0; i < serverBlock.getLocations().size(); i++) { - std::cout << "Location: " << serverBlock.getLocations()[i]._path << " == " << request.getRequestTarget() - << std::endl; + Debug::log("Location: " + serverBlock.getLocations()[i]._path + " == " + request.getRequestTarget(), Debug::SERVER); if (request.getRequestTarget() == serverBlock.getLocations()[i]._path) { - std::cout << "Location found" << std::endl; + Debug::log("Location found", Debug::SERVER); directive = serverBlock.getLocations()[i]; break; } diff --git a/src/ServerSocket.cpp b/src/ServerSocket.cpp index 35b912b9..54bc8f64 100644 --- a/src/ServerSocket.cpp +++ b/src/ServerSocket.cpp @@ -6,7 +6,7 @@ ServerSocket::ServerSocket() _serverFD = -1; _listen = Listen(); memset(&_serverSocketAddr, 0, sizeof(_serverSocketAddr)); - std::cout << "ServerSocket default constructor" << std::endl; + Debug::log("ServerSocket default constructor", Debug::OCF); } ServerSocket::ServerSocket(int serverFD, Listen listen) @@ -81,33 +81,27 @@ std::string mapIPv4ToIPv6(const std::string &ipv4Address) void ServerSocket::prepareServerSocketAddr() { - std::cout << "Entering prepareServerSocketAddr" << std::endl; struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); // hints.ai_family = _listen.getIsIpv6() ? AF_INET6 : AF_INET; hints.ai_family = AF_INET6; - std::cout << "hints.ai_family: " << hints.ai_family << std::endl; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; std::string port = toString(_listen.getPort()); - std::cout << "port: " << port << std::endl; - std::cout << "ip: " << _listen.getIp() << std::endl; std::string ip; if (!_listen.getIp().empty() && !_listen.getIsIpv6()) { - std::cout << "IPv4 address detected" << std::endl; std::string ipv6Address = mapIPv4ToIPv6(_listen.getIp()); - std::cout << "ipv6Address: " << ipv6Address << std::endl; ip = ipv6Address; } else ip = _listen.getIp(); - std::cout << "ip: " << ip << std::endl; + Debug::log("ip: " + ip, Debug::OCF); // Map IPv4 to IPv6 int status = getaddrinfo(ip.c_str(), port.c_str(), &hints, &res); - std::cout << "getaddrinfo status: " << status << std::endl; + Debug::log("getaddrinfo status: " + toString(status), Debug::OCF); if (status != 0) { std::cerr << "getaddrinfo: " << gai_strerror(status) << std::endl; @@ -118,11 +112,11 @@ void ServerSocket::prepareServerSocketAddr() std::cerr << "getaddrinfo: res is NULL" << std::endl; return; } - std::cout << "Before memcpy, port: " << ntohs(((struct sockaddr_in *)res->ai_addr)->sin_port) << std::endl; - std::cout << "Before memcpy, ip: " << inet_ntoa(((struct sockaddr_in *)res->ai_addr)->sin_addr) << std::endl; + // std::cout << "Before memcpy, port: " << ntohs(((struct sockaddr_in *)res->ai_addr)->sin_port) << std::endl; + // std::cout << "Before memcpy, ip: " << inet_ntoa(((struct sockaddr_in *)res->ai_addr)->sin_addr) << std::endl; memcpy(&_serverSocketAddr, res->ai_addr, res->ai_addrlen); - std::cout << "After memcpy, port: " << ntohs(((struct sockaddr_in *)&_serverSocketAddr)->sin_port) << std::endl; - std::cout << "After memcpy, ip: " << inet_ntoa(((struct sockaddr_in *)&_serverSocketAddr)->sin_addr) << std::endl; + // std::cout << "After memcpy, port: " << ntohs(((struct sockaddr_in *)&_serverSocketAddr)->sin_port) << std::endl; + // std::cout << "After memcpy, ip: " << inet_ntoa(((struct sockaddr_in *)&_serverSocketAddr)->sin_addr) << std::endl; freeaddrinfo(res); } diff --git a/src/StaticContentHandler.cpp b/src/StaticContentHandler.cpp index 097f98bd..2f21eeb6 100644 --- a/src/StaticContentHandler.cpp +++ b/src/StaticContentHandler.cpp @@ -49,11 +49,10 @@ static bool isDirectory(const std::string &path) void StaticContentHandler::handleRequest(HTTPRequest &request, HTTPResponse &response) { std::string requestTarget = request.getRequestTarget(); - std::string webRoot = "var/www"; std::string host = request.getHost(); std::string path = request.getPath(); - std::cout << "path: " << path << std::endl; + Debug::log("path: " + path, Debug::NORMAL); if (requestTarget == "/" || requestTarget == "") requestTarget = "/index.html"; // if the last character of the path is a / and the first character of the request target is a /, we remove the @@ -62,12 +61,11 @@ void StaticContentHandler::handleRequest(HTTPRequest &request, HTTPResponse &res requestTarget = requestTarget.substr(1); request.setRequestTarget(requestTarget); - std::cout << "requestTarget: " << request.getRequestTarget() << std::endl; + Debug::log("requestTarget: " + request.getRequestTarget(), Debug::NORMAL); // TODO: consider streaming the file instead of loading it all in memory for large files if (isDirectory(path)) - { path += "index.html"; - } + std::ifstream file(path.c_str()); if (!file) // TODO: this is wrong, it should return a false bool { @@ -90,8 +88,6 @@ void StaticContentHandler::handleRequest(HTTPRequest &request, HTTPResponse &res // response.setHeader("Connection: ", "close"); // response.setHeader("Server: ", "webserv"); - // std::cout << std::endl; - // std::cout << "_body : " << response.getBody() << std::endl; file.close(); return; } diff --git a/src/UploadHandler.cpp b/src/UploadHandler.cpp index b8b8c50f..fc21d127 100644 --- a/src/UploadHandler.cpp +++ b/src/UploadHandler.cpp @@ -59,7 +59,7 @@ bool UploadHandler::checkFiles(const HTTPRequest &request) { if (it->headers.find("filename") == it->headers.end()) { - std::cout << "422 Unprocessable Entity (Error: file does not have a name)" << std::endl; + Debug::log("422 Unprocessable Entity (Error: file does not have a name)", Debug::NORMAL); return false; } } @@ -67,7 +67,7 @@ bool UploadHandler::checkFiles(const HTTPRequest &request) { if (it->fileContent.empty()) { - std::cout << "422 Unprocessable Entity (Error: file is empty)" << std::endl; + Debug::log("422 Unprocessable Entity (Error: file does not have a name)", Debug::NORMAL); return false; } } @@ -78,13 +78,12 @@ bool UploadHandler::checkFiles(const HTTPRequest &request) std::string extension = filename.substr(filename.find_last_of(".") + 1); if (extension.empty()) { - // TODO: have an html ? - std::cout << "415 Unsupported Media Type (Error: file has no extension)" << std::endl; + Debug::log("415 Unsupported Media Type (Error: file has no extension)", Debug::NORMAL); return false; } if (isHarmfulExtension(extension)) { - std::cout << "415 Unsupported Media Type (Error: file has a harmful extension)" << std::endl; + Debug::log("415 Unsupported Media Type (Error: file has no extension)", Debug::NORMAL); return false; } } @@ -98,24 +97,23 @@ bool UploadHandler::createFile(HTTPRequest &request) else _uploadDir = request.getRoot() + request.getHost() + "/" + _uploadDir; - std::cout << "Creating file at " << _uploadDir << std::endl; std::vector files = request.getFiles(); std::vector::iterator it; for (it = files.begin(); it != files.end(); ++it) { std::string filePath = _uploadDir + (it->headers.find("filename"))->second; - std::cout << "Creating file at " << filePath << std::endl; + Debug::log("Creating file at " + filePath, Debug::NORMAL); std::ofstream outfile(filePath.c_str()); if (outfile.is_open()) { outfile << it->fileContent; outfile.close(); - std::cout << "File created successfully at " << filePath << std::endl; + Debug::log("File created successfully at " + filePath, Debug::NORMAL); } else { - std::cout << "422 Unprocessable Entity (Error creating a file at " << filePath << ")" << std::endl; + Debug::log("422 Unprocessable Entity (Error creating a file at " + filePath + ")", Debug::NORMAL); return (false); } } @@ -136,12 +134,11 @@ bool UploadHandler::createFileChunked(HTTPRequest &request) { outfile << request.getBody(); outfile.close(); - std::cout << "File created successfully at " << _uploadDir << std::endl; + Debug::log("File created successfully at " + _uploadDir, Debug::NORMAL); } else { - - std::cout << "422 Unprocessable Entity (Error creating a file at " << _uploadDir << ")" << std::endl; + Debug::log("422 Unprocessable Entity (Error creating a file at " + _uploadDir + ")", Debug::NORMAL); return (false); } return (true); @@ -151,13 +148,11 @@ void UploadHandler::handleRequest(HTTPRequest &request, HTTPResponse &response) { if (!checkFiles(request)) { - std::cout << PURPLE << "calling handle response" << RESET << std::endl; handleResponse(response, BAD_REQUEST); return; } if (!request.getUploadBoundary().empty()) { - std::cout << PURPLE << "calling upload boundary" << RESET << std::endl; if (!createFile(const_cast(request))) return (response.setStatusCode(422, "Unprocessable Entity")); handleResponse(response, SUCCESS); @@ -166,12 +161,10 @@ void UploadHandler::handleRequest(HTTPRequest &request, HTTPResponse &response) { // logic is incorrect here in case of chunked request // temporary solution - std::cout << PURPLE << "calling create file chunked" << RESET << std::endl; if (!createFileChunked(const_cast(request))) return (response.setStatusCode(422, "Unprocessable Entity")); handleResponse(response, SUCCESS); - // std::cout << "415 Unsupported Media Type" << std::endl; - // handleResponse(response, BAD_REQUEST); + } } @@ -195,21 +188,21 @@ void UploadHandler::handleResponse(HTTPResponse &response, enum UploadStatus sta if (status == SUCCESS) { - std::cout << "Upload: File created successfully" << std::endl; + Debug::log("Upload: File created successfully", Debug::NORMAL); fileContents = readFileContents("html/success/200_upload_success.html"); statusCode = 200; response.setStatusCode(statusCode, "OK"); } else if (status == BAD_REQUEST) { - std::cout << "Upload: Bad request" << std::endl; + Debug::log("Upload: Bad request", Debug::NORMAL); fileContents = readFileContents("html/errors/400.html"); statusCode = 400; response.setStatusCode(statusCode, "Bad Request"); } else { - std::cout << "Upload: Internal server error" << std::endl; + Debug::log("Upload: Internal server error", Debug::NORMAL); fileContents = "

Unknown Error

"; statusCode = 500; response.setStatusCode(statusCode, "Internal Server Error"); From 34f26b1a4a2728864e201cecaa290b03805ae956 Mon Sep 17 00:00:00 2001 From: dantol29 Date: Wed, 22 May 2024 14:12:15 +0200 Subject: [PATCH 05/17] fix(compile): fix compilation error --- src/HTTPResponse.cpp | 11 ++++++----- src/Router.cpp | 2 +- src/Server.cpp | 8 ++++---- src/Server.hpp | 2 +- src/ServerSocket.cpp | 5 +++-- src/main.cpp | 6 ++---- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/HTTPResponse.cpp b/src/HTTPResponse.cpp index 96c3fc93..3b0ed8b1 100644 --- a/src/HTTPResponse.cpp +++ b/src/HTTPResponse.cpp @@ -33,7 +33,7 @@ std::string HTTPResponse::objToString() const std::stringstream responseStream; if (_statusCode == 0) { - std::cerr << "\033[31mWarning: Sending a response with status code 0\033[0m" << std::endl; + Debug::log("Sending a response with status code 0", Debug::NORMAL); } responseStream << "HTTP/1.1 " << _statusCode << " " << getStatusMessage(_statusCode) << "\r\n"; for (size_t i = 0; i < _headers.size(); ++i) @@ -70,12 +70,13 @@ int HTTPResponse::getStatusCode() const void HTTPResponse::setStatusCode(int statusCode, const std::string &message) { if (!message.empty()) - std::cerr << message << std::endl; + Debug::log(message, Debug::NORMAL); if (_statusCode != 0) { - std::cerr << "\033[31mWarning: Overwriting existing status code (" << _statusCode << ") and message (" - << _statusMessage << ") with new code (" << statusCode << ") and message (" - << getStatusMessage(statusCode) << ").\033[0m" << std::endl; + Debug::log("Warning: Overwriting existing status code (" + toString(_statusCode) + ") and message (" + + _statusMessage + ") with new code (" + toString(statusCode) + ") and message (" + + getStatusMessage(statusCode) + ").", + Debug::NORMAL); } _statusCode = statusCode; diff --git a/src/Router.cpp b/src/Router.cpp index bc36183e..69b928ad 100644 --- a/src/Router.cpp +++ b/src/Router.cpp @@ -69,7 +69,7 @@ void Router::routeRequest(HTTPRequest &request, HTTPResponse &response) Debug::log("Routing Request: path = " + request.getPath(), Debug::NORMAL); PathValidation pathResult = pathIsValid(response, request); - Debug::log("Routing Request: pathResult = " + std::to_string(pathResult), Debug::NORMAL); + Debug::log("Routing Request: pathResult = " + toString(pathResult), Debug::NORMAL); Debug::log("Path requested: " + request.getPath(), Debug::NORMAL); // check if method is allowed diff --git a/src/Server.cpp b/src/Server.cpp index de34d95d..b71eaf5f 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -54,7 +54,7 @@ const EventManager &Server::getEventManager() const void Server::startListening() { createServerSockets(_serverBlocks); - printServerSockets(); + //printServerSockets(); setReuseAddrAndPort(); checkSocketOptions(); bindToPort(); @@ -124,8 +124,8 @@ void Server::waitCGI() Debug::log("PID: " + toString(pid), Debug::CGI); for (size_t i = 0; i < originalSize && i < _FDs.size(); i++) - Debug::log("PID: " + toString(_connections[i].getCGIPid() + ", hasCGI: " + \ - toString(_connections[i].getHasCGI())), Debug::CGI); + Debug::log("PID: " + toString(_connections[i].getCGIPid()) + ", hasCGI: " + \ + toString(_connections[i].getHasCGI()), Debug::CGI); if (pid > 0) { @@ -561,7 +561,7 @@ void Server::createServerSockets(std::vector &serverBlocks) } else { - std::cout << "IPV6_V6ONLY: " << ipv6only << std::endl; + Debug::log("IPV6_V6ONLY: " + toString(ipv6only), Debug::SERVER); } ServerSocket serverSocket(serverFD, *it); _serverSockets.push_back(serverSocket); diff --git a/src/Server.hpp b/src/Server.hpp index 3fd75d9a..98d7457a 100644 --- a/src/Server.hpp +++ b/src/Server.hpp @@ -21,7 +21,7 @@ #include "ServerSocket.hpp" #include "EventManager.hpp" -#define VERBOSE 1 +#define VERBOSE 0 class Connection; // Forward declaration for circular dependencyA diff --git a/src/ServerSocket.cpp b/src/ServerSocket.cpp index 54bc8f64..8ffc4ad2 100644 --- a/src/ServerSocket.cpp +++ b/src/ServerSocket.cpp @@ -122,8 +122,9 @@ void ServerSocket::prepareServerSocketAddr() std::ostream &operator<<(std::ostream &out, const ServerSocket &socket) { - out << "Fd: " << socket.getServerFD() << std::endl; - out << "Listen: " << socket.getListen() << std::endl; + (void)socket; + //out << "Fd: " << socket.getServerFD() << std::endl; + //out << "Listen: " << socket.getListen() << std::endl; // out << "ServerSocketAddr: " << socket.getServerSocketAddr() << std::endl; return out; } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index a0a18ab8..7082584c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,7 +6,7 @@ int main(int argc, char **argv) { - Debug::enable(true); + Debug::enable(false); Debug::setLevel(Debug::NORMAL); if (argc > 2) @@ -19,7 +19,7 @@ int main(int argc, char **argv) if (!config.getErrorMessage().empty()) return 1; - std::cout << config << std::endl; // should be in the DEBUG? + //std::cout << config << std::endl; // should be in the DEBUG? EventManager eventManager; Server webserv(config, eventManager); @@ -27,8 +27,6 @@ int main(int argc, char **argv) eventManager.subscribe(&serverEventListener); - std::cout << &webserv.getEventManager() << std::endl; - webserv.startListening(); webserv.startPollEventLoop(); From e9ad2b56d91c3f06b20f16227e7a4b1ee6f11caa Mon Sep 17 00:00:00 2001 From: dantol29 Date: Wed, 22 May 2024 14:29:35 +0200 Subject: [PATCH 06/17] feat(writeTOCLient): add response messag to the terminal --- src/Server.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Server.cpp b/src/Server.cpp index b71eaf5f..a4537ffd 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -432,6 +432,14 @@ void Server::writeToClient(Connection &conn, size_t &i, HTTPResponse &response) { tmpBufferSize = conn.getResponseString().size(); Debug::log("Sending last part of the response", Debug::NORMAL); + if (conn.getResponse().getStatusCode() < 300) + std::cout << GREEN << conn.getRequest().getMethod() << " " << conn.getResponse().getStatusCode() << " " << \ + conn.getResponse().getStatusMessage() << \ + " " << conn.getRequest().getRequestTarget() << RESET << std::endl; + else + std::cout << RED << conn.getRequest().getMethod() << " " << conn.getResponse().getStatusCode() << " " << \ + conn.getResponse().getStatusMessage() << \ + " " << conn.getRequest().getRequestTarget() << RESET << std::endl; isLastSend = true; } From 2f25aaaa46cf6162e9cfe8ce57c31e4a13c98339 Mon Sep 17 00:00:00 2001 From: dantol29 Date: Thu, 23 May 2024 16:31:22 +0200 Subject: [PATCH 07/17] fix(compile): fix compilation errors --- src/CGIHandler.cpp | 16 ++++++++-------- src/Server.cpp | 37 +++++++++++-------------------------- src/events/EventManager.cpp | 2 +- 3 files changed, 20 insertions(+), 35 deletions(-) diff --git a/src/CGIHandler.cpp b/src/CGIHandler.cpp index 1192a05a..0d0d9b7a 100644 --- a/src/CGIHandler.cpp +++ b/src/CGIHandler.cpp @@ -167,7 +167,7 @@ bool CGIHandler::executeCGI(const MetaVariables &env, HTTPResponse &response) response.setIsCGI(true); response.setCGIpipeFD(pipeFD); - std::cout << "PIPE SAVED: "<< *response.getCGIpipeFD() << std::endl; + Debug::log("PIPE SAVED: " + toString(*response.getCGIpipeFD()), Debug::CGI); close(pipeFD[1]); EventData data = {1, pid, pipeFD[0], pipeFD[1]}; // Assuming 1 is the event type for CGI started @@ -175,16 +175,16 @@ bool CGIHandler::executeCGI(const MetaVariables &env, HTTPResponse &response) _eventManager.emit(data); // Emit event indicating a CGI process has started _connection.addCGI(pid); - std::cout << GREEN << _connection.getCGIPid() << RESET << std::endl; + Debug::log("CGIHandler: CGI PID: " + toString(pid), Debug::CGI); // clang-format off - std::vector > pipes = _eventManager.getPipeFDs(); - for (std::vector >::const_iterator it = pipes.begin(); it != pipes.end(); ++it) - { - std::cout << GREEN << "CGIHandler: pipeFDs: " << (*it).first << RESET << std::endl; - } + // std::vector > pipes = _eventManager.getPipeFDs(); + // for (std::vector >::const_iterator it = pipes.begin(); it != pipes.end(); ++it) + // { + // std::cout << GREEN << "CGIHandler: pipeFDs: " << (*it).first << RESET << std::endl; + // } // clang-format on - std::cout << RED << "Exiting CGIHandler::executeCGI with true" << RESET << std::endl; + Debug::log("CGIHandler: Waiting for CGI to finish", Debug::CGI); return true; } diff --git a/src/Server.cpp b/src/Server.cpp index c7202c0b..93367bed 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -72,11 +72,11 @@ void Server::startPollEventLoop() while (1) { if (_hasCGI) - timeout = 1000; // 1 seconds + timeout = 500; // 0.5 seconds else if (_clientCounter > 0) { - std::cout << BLUE << "Client counter: " << _clientCounter << RESET << std::endl; - timeout = 5000; // 15 seconds + Debug::log("Client counter: " + toString(_clientCounter), Debug::SERVER); + timeout = 15000; // 15 seconds } else timeout = -1; @@ -85,8 +85,8 @@ void Server::startPollEventLoop() " Waiting for new connection or Polling +++++++++++++++" + toString(RESET), Debug::SERVER); int ret = poll(_FDs.data(), _FDs.size(), timeout); pollCounter++; - printFrame("POLL EVENT DETECTED", true); - printConnections("AFTER POLL", _FDs, _connections, true); + //printFrame("POLL EVENT DETECTED", true); + //printConnections("AFTER POLL", _FDs, _connections, true); if (ret > 0) { size_t originalSize = _FDs.size(); @@ -164,7 +164,7 @@ void Server::waitCGI() double elapsed = difftime(time(NULL), _connections[i].getCGIStartTime()); Debug::log("Elapsed time: " + toString(elapsed) + " seconds", Debug::CGI); - if (_connections[i].getHasCGI() && elapsed > 1) + if (_connections[i].getHasCGI() && elapsed > 10) // 10 seconds { Debug::log("CGI timed out", Debug::NORMAL); @@ -371,7 +371,7 @@ void Server::readCGIPipe(Connection &conn, HTTPResponse &response) ssize_t bytesRead; bytesRead = read(pipeFD[0], readBuffer, CGI_BUFFER_SIZE - 1); - std::cout << "Bytes read: " << bytesRead << std::endl; + Debug::log("Bytes read: " + toString(bytesRead), Debug::CGI); if (bytesRead > 0) { readBuffer[bytesRead] = '\0'; @@ -485,8 +485,7 @@ void Server::handleConnection(Connection &conn, size_t &i) if (conn.getHasReadSocket() && !conn.getHasFinishedReading()) return; - } - std::cout << request << std::endl; + if (!conn.getCanBeClosed() && !conn.getHasDataToSend()) buildResponse(conn, i, request, response); // MInd that after the last read from the pipe of the CGI getHasReadSocket will be false but we will have a read @@ -496,11 +495,6 @@ void Server::handleConnection(Connection &conn, size_t &i) if (conn.getCanBeClosed()) closeClientConnection(conn, i); - - // Validate the CGI pipe file descriptors before accessingjj - // TODO: following line get an overflow on mac - // std::cout << BLUE << *response.getCGIpipeFD() << RESET << std::endl; - std::cout << RED << "Exiting handleConnection" << RESET << std::endl; } /*** Private Methods ***/ @@ -754,8 +748,6 @@ void Server::acceptNewConnection(Connection &conn) _FDs.push_back(newSocketPoll); _connections.push_back(newConnection); ++_clientCounter; - std::cout << newConnection.getHasFinishedReading() << std::endl; - std::cout << _connections.back().getHasFinishedReading() << std::endl; /* end together */ if (VERBOSE) { @@ -819,11 +811,9 @@ void Server::handleClientSocketError(int clientFD, size_t &i) perror("poll client socket error"); } +// Is not the socket timeout, but the poll timeout void Server::handleSocketTimeoutIfAny() { - // Is not the socket timeout, but the poll timeout - std::cout << "Timeout occurred!" << std::endl; - // loop through the connections and check for timeout for (size_t i = 0; i < _FDs.size(); i++) { @@ -831,9 +821,9 @@ void Server::handleSocketTimeoutIfAny() continue; double elapsed = difftime(time(NULL), _connections[i].getStartTime()); - if (elapsed > 3) + if (elapsed > 10000) // 10 seconds { - std::cout << RED << "Elapsed time: " << elapsed << " seconds" << RESET << std::endl; + Debug::log("Elapsed time: " + toString(elapsed) + " seconds", Debug::SERVER); // We have to send a 408 Request Timeout _connections[i].getResponse().setStatusCode(408, "Request Timeout"); buildResponse(_connections[i], i, _connections[i].getRequest(), _connections[i].getResponse()); @@ -973,11 +963,6 @@ void Server::findLocationBlock(HTTPRequest &request, ServerBlock &serverBlock, D void Server::addPipeFDs(int pipe0, int pipe1) { _pipeFDs.push_back(std::make_pair(pipe0, pipe1)); - // print the pipe fds - for (size_t i = 0; i < _pipeFDs.size(); i++) - { - std::cout << PURPLE << "Pipe FDs: " << _pipeFDs[i].first << RESET << std::endl; - } } // clang-format off diff --git a/src/events/EventManager.cpp b/src/events/EventManager.cpp index fff42833..4cbd32fb 100644 --- a/src/events/EventManager.cpp +++ b/src/events/EventManager.cpp @@ -48,7 +48,7 @@ void EventManager::emit(const EventData &eventData) { ServerEventListener *serverEventListener = dynamic_cast(*it); (*it)->handleEvent(eventData); - std::cout << RED << serverEventListener->getServer().getCGICounter() << RESET << std::endl; + //std::cout << RED << serverEventListener->getServer().getCGICounter() << RESET << std::endl; _pipeFDs = serverEventListener->getServer().getPipeFDs(); } } From 55e807d4ac17bf35e7607b6c62e0cab16684917f Mon Sep 17 00:00:00 2001 From: dantol29 Date: Thu, 23 May 2024 16:38:53 +0200 Subject: [PATCH 08/17] fix(header): add defines for timeouts --- include/webserv.hpp | 5 ++++- src/CGIHandler.cpp | 4 ++-- src/Server.cpp | 11 ++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/webserv.hpp b/include/webserv.hpp index e022e581..7acd90aa 100644 --- a/include/webserv.hpp +++ b/include/webserv.hpp @@ -17,7 +17,10 @@ #define SEND_BUFFER_SIZE 1024 * 100 // 100 KB #define BUFFER_SIZE 1025 -#define CGI_TIMEOUT_MS 10000 +#define CGI_TIMEOUT_MS 10000 // 10 seconds +#define CGI_POLL_TIMEOUT_MS 500 // 0.5 seconds +#define CLIENT_POLL_TIMEOUT_MS 15000 // 15 seconds +#define CLIENT_TIMEOUT_MS 10000 // 10 seconds #define CONFIG_FILE_DEFAULT_PATH "./conf/webserv_default.conf" #define RED "\033[1;31m" diff --git a/src/CGIHandler.cpp b/src/CGIHandler.cpp index 0d0d9b7a..e2a43cb8 100644 --- a/src/CGIHandler.cpp +++ b/src/CGIHandler.cpp @@ -147,7 +147,7 @@ bool CGIHandler::executeCGI(const MetaVariables &env, HTTPResponse &response) if (access(argvPointers[0], X_OK) == -1) { - perror("access"); + Debug::log("CGIHandler: access failed", Debug::CGI); return false; _exit(EXIT_FAILURE); // TODO: @leo I don't think we should exit here. We don't want to kill the whole server cause of a CGI @@ -157,7 +157,7 @@ bool CGIHandler::executeCGI(const MetaVariables &env, HTTPResponse &response) // execve(argvPointers[0], argvPointers.data(), envpPointers.data()); if (execve(argvPointers[0], argvPointers.data(), envpPointers.data()) == -1) { - perror("execve"); + Debug::log("CGIHandler: execve failed", Debug::CGI); return false; // TODO: @leo We should check if execve failed and return an error response and not exti _exit(EXIT_FAILURE); diff --git a/src/Server.cpp b/src/Server.cpp index 93367bed..3ca55754 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -72,12 +72,9 @@ void Server::startPollEventLoop() while (1) { if (_hasCGI) - timeout = 500; // 0.5 seconds + timeout = CGI_POLL_TIMEOUT_MS; // 0.5 seconds else if (_clientCounter > 0) - { - Debug::log("Client counter: " + toString(_clientCounter), Debug::SERVER); - timeout = 15000; // 15 seconds - } + timeout = CLIENT_POLL_TIMEOUT_MS; // 15 seconds else timeout = -1; //printConnections("BEFORE POLL", _FDs, _connections, true); @@ -164,7 +161,7 @@ void Server::waitCGI() double elapsed = difftime(time(NULL), _connections[i].getCGIStartTime()); Debug::log("Elapsed time: " + toString(elapsed) + " seconds", Debug::CGI); - if (_connections[i].getHasCGI() && elapsed > 10) // 10 seconds + if (_connections[i].getHasCGI() && elapsed > CGI_TIMEOUT_MS) // 10 seconds { Debug::log("CGI timed out", Debug::NORMAL); @@ -821,7 +818,7 @@ void Server::handleSocketTimeoutIfAny() continue; double elapsed = difftime(time(NULL), _connections[i].getStartTime()); - if (elapsed > 10000) // 10 seconds + if (elapsed > CLIENT_TIMEOUT_MS) // 10 seconds { Debug::log("Elapsed time: " + toString(elapsed) + " seconds", Debug::SERVER); // We have to send a 408 Request Timeout From 7567f510db3134ec86d4eaf7d5f31a82f0c02070 Mon Sep 17 00:00:00 2001 From: dantol29 Date: Thu, 23 May 2024 16:52:33 +0200 Subject: [PATCH 09/17] fix(tests): add more tests adn fix c++ parser test --- include/webserv.hpp | 6 +++--- src/Server.cpp | 5 +++-- src/main.cpp | 4 ++-- tests/error_codes.sh | 36 ++++++++++++++++++++++++++++++++++++ tests/parser.cpp | 8 ++++---- 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/include/webserv.hpp b/include/webserv.hpp index 7acd90aa..d7f71d02 100644 --- a/include/webserv.hpp +++ b/include/webserv.hpp @@ -17,10 +17,10 @@ #define SEND_BUFFER_SIZE 1024 * 100 // 100 KB #define BUFFER_SIZE 1025 -#define CGI_TIMEOUT_MS 10000 // 10 seconds +#define CGI_TIMEOUT_S 10 // 10 seconds #define CGI_POLL_TIMEOUT_MS 500 // 0.5 seconds -#define CLIENT_POLL_TIMEOUT_MS 15000 // 15 seconds -#define CLIENT_TIMEOUT_MS 10000 // 10 seconds +#define CLIENT_POLL_TIMEOUT_MS 10000 // 10 seconds +#define CLIENT_TIMEOUT_S 7 // 7 seconds #define CONFIG_FILE_DEFAULT_PATH "./conf/webserv_default.conf" #define RED "\033[1;31m" diff --git a/src/Server.cpp b/src/Server.cpp index 3ca55754..b6d2fa6b 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -161,7 +161,7 @@ void Server::waitCGI() double elapsed = difftime(time(NULL), _connections[i].getCGIStartTime()); Debug::log("Elapsed time: " + toString(elapsed) + " seconds", Debug::CGI); - if (_connections[i].getHasCGI() && elapsed > CGI_TIMEOUT_MS) // 10 seconds + if (_connections[i].getHasCGI() && elapsed > CGI_TIMEOUT_S) // 10 seconds { Debug::log("CGI timed out", Debug::NORMAL); @@ -818,7 +818,8 @@ void Server::handleSocketTimeoutIfAny() continue; double elapsed = difftime(time(NULL), _connections[i].getStartTime()); - if (elapsed > CLIENT_TIMEOUT_MS) // 10 seconds + Debug::log("Elapsed time: " + toString(elapsed) + " seconds", Debug::SERVER); + if (elapsed > CLIENT_TIMEOUT_S) // 10 seconds { Debug::log("Elapsed time: " + toString(elapsed) + " seconds", Debug::SERVER); // We have to send a 408 Request Timeout diff --git a/src/main.cpp b/src/main.cpp index 07308b61..b9758588 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,8 +6,8 @@ int main(int argc, char **argv) { - Debug::enable(false); - Debug::setLevel(Debug::NORMAL); + Debug::enable(true); + Debug::setLevel(Debug::SERVER); if (argc > 2) { diff --git a/tests/error_codes.sh b/tests/error_codes.sh index c6aaf569..6099397d 100755 --- a/tests/error_codes.sh +++ b/tests/error_codes.sh @@ -67,6 +67,42 @@ else echo -e "$RED www.python_site.com:8080: $response $RESET" fi +response=$(curl -s -o /dev/null -w "%{http_code}" -H "Host: www.development_site" http://127.0.0.1:8080/cgi-bin/error.cgi) + +if [ "$response" -eq 500 ]; then + echo -e "$GREEN www.development_site.com:8080: 500(Internal Server Error) $RESET" +else + echo -e "$RED www.development_site.com:8080: $response $RESET" + is_error=true +fi + +response=$(curl -s -o /dev/null -w "%{http_code}" -H "Host: www.development_site" http://127.0.0.1:8080/cgi-bin/permission.cgi) + +if [ "$response" -eq 500 ]; then + echo -e "$GREEN www.development_site.com:8080: 500(Internal Server Error) $RESET" +else + echo -e "$RED www.development_site.com:8080: $response $RESET" + is_error=true +fi + +response=$(curl -s -o /dev/null -w "%{http_code}" -H "Host: www.development_site" http://127.0.0.1:8080/cgi-bin/hello_var.cgi) + +if [ "$response" -eq 200 ]; then + echo -e "$GREEN www.development_site.com:8080: 200 $RESET" +else + echo -e "$RED www.development_site.com:8080: $response $RESET" + is_error=true +fi + +response=$(curl -s -o /dev/null -w "%{http_code}" -H "Host: www.development_site" http://127.0.0.1:8080/cgi-bin/duration_ts.cgi) + +if [ "$response" -eq 200 ]; then + echo -e "$GREEN www.development_site.com:8080: 200 $RESET" +else + echo -e "$RED www.development_site.com:8080: $response $RESET" + is_error=true +fi + if [ "$is_error" = true ]; then exit 1 fi diff --git a/tests/parser.cpp b/tests/parser.cpp index cc475d8b..b330d204 100644 --- a/tests/parser.cpp +++ b/tests/parser.cpp @@ -134,7 +134,7 @@ void sendData(const std::vector &tests, sockaddr_in serverAddress) ssize_t bytesSent = send(clientSocket, test.request.c_str(), test.request.size(), 0); char buffer[BUFFER_SIZE]; - if (waitForResponseWitPoll(clientSocket, POLL_TIMOUT * 100)) + if (waitForResponseWitPoll(clientSocket, POLL_TIMOUT * 15)) { ssize_t bytesRead = read(clientSocket, buffer, BUFFER_SIZE); if (bytesRead < 0) @@ -281,18 +281,18 @@ int main(int argc, char **argv) // if (std::strcmp(argv[1], "query") == 0) std::cout << "\033[38;5;214mRunning query tests\033[0m" << std::endl; - // query(serverAddress); + query(serverAddress); // else if (std::strcmp(argv[1], "simple") == 0) std::cout << "\033[38;5;214mQuery tests done\033[0m" << std::endl; std::cout << "\033[38;5;214mRunning simple tests\033[0m" << std::endl; - // simple(serverAddress); + simple(serverAddress); std::cout << "\033[38;5;214mSimple tests done\033[0m" << std::endl; std::cout << "\033[38;5;214mRunning headers tests\033[0m" << std::endl; // else if (std::strcmp(argv[1], "headers") == 0) headers(serverAddress); std::cout << "\033[38;5;214mHeaders tests done\033[0m" << std::endl; // else if (std::strcmp(argv[1], "body") == 0) - // body(serverAddress); + body(serverAddress); // else // std::cout << "Invalid test name" << std::endl; if (is_error) From a4e2ab90519ecb16363640d40fb8272737b52020 Mon Sep 17 00:00:00 2001 From: dantol29 Date: Thu, 23 May 2024 17:06:00 +0200 Subject: [PATCH 10/17] tests(parser): add test with wrong content-length --- tests/parser.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/parser.cpp b/tests/parser.cpp index b330d204..28dd9403 100644 --- a/tests/parser.cpp +++ b/tests/parser.cpp @@ -225,10 +225,9 @@ void body(sockaddr_in serverAddress) HTTPTest("POST / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 17\r\nContent-Type: " "text/plain\r\n\r\nThis\r\nis body\r\n\r\n", "200"), - // TODO: // HTTPTest("POST / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 17\r\nContent-Type: " - // "text/plain\r\n\r\nThis\r\nis body\r\n", - // "400"),// 400 (Bad Request) -- - Wrong content length // This case is complicated: we have an extra - // linera issue for it!} + HTTPTest("POST / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 100\r\nContent-Type: " + "text/plain\r\n\r\nThis\r\nis body\r\n\r\n", + "408"),// 408 (Timeout) -- - Wrong content length HTTPTest("POST / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 16\r\nContent-Type: " "text/plain\r\n\r\nThis\r\nis body\r\n\n", "200"), // 200 body shouldn't end with CRLF @@ -238,10 +237,10 @@ void body(sockaddr_in serverAddress) HTTPTest("POST / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 16\r\nContent-Type: " "text/plain\r\n\r\nThis\ris body\r\n\r\n", "200"), - // HTTPTest( - // "POST / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 17\r\nContent-Type: " - // "text/plain\r\n\r\nThis\r\n\r\nis body\r\n\r\n", - // "400"), // 400 (Bad Request) -- - Improper line termination of the body // with '\r' // TODO: are you sure?} + HTTPTest( + "POST / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 17\r\nContent-Type: " + "text/plain\r\n\r\nThis\r\n\r\nis body\r\n\r\n", + "400"), // 400 (Bad Request) -- - Improper line termination of the body // with '\r' // TODO: are you sure?} HTTPTest("GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 17\r\nContent-Type: " "text/plain\r\n\r\nThis\r\nis body\r\n\r\n", "200"), // GET request with body is correct From 119c421b986935dbc083bf07bf4a6e0885dcbdae Mon Sep 17 00:00:00 2001 From: dantol29 Date: Thu, 23 May 2024 17:09:00 +0200 Subject: [PATCH 11/17] fix(tests): remove incorrect test --- tests/parser.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/parser.cpp b/tests/parser.cpp index 28dd9403..1245e0af 100644 --- a/tests/parser.cpp +++ b/tests/parser.cpp @@ -237,10 +237,6 @@ void body(sockaddr_in serverAddress) HTTPTest("POST / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 16\r\nContent-Type: " "text/plain\r\n\r\nThis\ris body\r\n\r\n", "200"), - HTTPTest( - "POST / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 17\r\nContent-Type: " - "text/plain\r\n\r\nThis\r\n\r\nis body\r\n\r\n", - "400"), // 400 (Bad Request) -- - Improper line termination of the body // with '\r' // TODO: are you sure?} HTTPTest("GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 17\r\nContent-Type: " "text/plain\r\n\r\nThis\r\nis body\r\n\r\n", "200"), // GET request with body is correct From 27af6d5a04f2c5dec3edc8892662acaa62493f34 Mon Sep 17 00:00:00 2001 From: dantol29 Date: Thu, 23 May 2024 17:50:28 +0200 Subject: [PATCH 12/17] chore(conf): add tricky conf file --- conf/single.conf | 5 +++-- src/main.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/conf/single.conf b/conf/single.conf index 03242f19..67a01add 100644 --- a/conf/single.conf +++ b/conf/single.conf @@ -1,5 +1,6 @@ server { - listen 127.0.0.1:8080; + listen 127.0.0.1:8080 8081 8082; + listen 127.0.0.2:8080; server_name www.saladbook; - root /var/www/html; + root /var/; } diff --git a/src/main.cpp b/src/main.cpp index b9758588..d1cc62ac 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,7 +6,7 @@ int main(int argc, char **argv) { - Debug::enable(true); + Debug::enable(false); Debug::setLevel(Debug::SERVER); if (argc > 2) From 40e28d2959db0d8441d0f3672a86eebdd251baa4 Mon Sep 17 00:00:00 2001 From: dantol29 Date: Fri, 24 May 2024 11:38:58 +0200 Subject: [PATCH 13/17] feat(Server): add connection limit check + new directive --- conf/webserv_default.conf | 11 +++++ src/Server.cpp | 42 ++++++++++++++++++- src/Server.hpp | 5 ++- src/ServerBlock.cpp | 29 ++++++++++++- src/ServerBlock.hpp | 4 ++ .../cgi-bin/duration_ts.cgi | 2 +- 6 files changed, 89 insertions(+), 4 deletions(-) diff --git a/conf/webserv_default.conf b/conf/webserv_default.conf index 12ccc97e..2589d38b 100644 --- a/conf/webserv_default.conf +++ b/conf/webserv_default.conf @@ -45,6 +45,7 @@ server { autoindex on; cgi_ext .cgi; server_name www.development_site; + limit_conn 3; allow_methods GET POST DELETE; root var/; } @@ -56,4 +57,14 @@ server { client_max_body_size 1000; autoindex off; root var/; +} + +server { + listen 8080; + server_name www.saladbook; + limit_conn 2; + allow_methods GET POST DELETE; + client_max_body_size 1000; + autoindex off; + root var/; } \ No newline at end of file diff --git a/src/Server.cpp b/src/Server.cpp index b6d2fa6b..ebbe5021 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -220,6 +220,14 @@ void Server::readFromClient(Connection &conn, size_t &i, Parser &parser, HTTPReq parser.parseRequestLineAndHeaders(parser.getHeadersBuffer().c_str(), request, response); if (parser.getHeadersAreParsed() && !conn.findServerBlock(_config.getServerBlocks())) Debug::log("Error finding server block", Debug::NORMAL); + + // check if connection limit is reached + if (isLimitConnReached(conn)) + { + response.setStatusCode(503, "Service Unavailable"); + conn.setHasFinishedReading(true); + } + } if (response.getStatusCode() != 0) @@ -463,6 +471,7 @@ void Server::closeClientConnection(Connection &conn, size_t &i) close(conn.getPollFd().fd); _FDs.erase(_FDs.begin() + i); _connections.erase(_connections.begin() + i); + _connectionsPerIP[conn.getServerIp()] -= 1; --_clientCounter; --i; } @@ -730,6 +739,13 @@ void Server::acceptNewConnection(Connection &conn) Connection newConnection(newSocketPoll, *this); newConnection.setType(CLIENT); newConnection.setServerIp(conn.getServerIp()); + + if (_connectionsPerIP.find(conn.getServerIp()) == _connectionsPerIP.end()) + _connectionsPerIP.insert(std::pair(conn.getServerIp(), 1)); + else + _connectionsPerIP[conn.getServerIp()] += 1; + + std::cout << "Server IP: " << conn.getServerIp() << std::endl; newConnection.setServerPort(conn.getServerPort()); if (VERBOSE) { @@ -968,4 +984,28 @@ std::vector > Server::getPipeFDs() const { return _pipeFDs; } -// clang-format on \ No newline at end of file +// clang-format on + +bool Server::isLimitConnReached(Connection &conn) +{ + if (conn.getHasServerBlock() == NOT_FOUND) + return (false); + + Directives directive = conn.getServerBlock().getDirectives(); + + if (directive._limit_conn != 0) + { + // loop through all the listen directives of the server block + for (size_t i = 0; i < directive._listen.size(); i++) + { + if (_connectionsPerIP[directive._listen[i].getIp()] > (int)directive._limit_conn) + { + std::cout << "number of connections: " << _connectionsPerIP[directive._listen[0].getIp()] << std::endl; + std::cout << "limit: " << directive._limit_conn << std::endl; + Debug::log("Connection limit reached", Debug::SERVER); + return (true); + } + } + } + return (false); +} \ No newline at end of file diff --git a/src/Server.hpp b/src/Server.hpp index 01335692..e99194e3 100644 --- a/src/Server.hpp +++ b/src/Server.hpp @@ -33,7 +33,7 @@ class Server void startListening(); void startPollEventLoop(); - + void printServerSockets() const; /* for CGI */ void setHasCGI(bool hasCGI); @@ -65,6 +65,8 @@ class Server int _clientCounter; bool _hasCGI; int _CGICounter; + // number of connections per IP + std::map _connectionsPerIP; /*** Private Methods ***/ Server(); @@ -84,6 +86,7 @@ class Server void handlePollError(); void AlertAdminAndTryToRecover(); void waitCGI(); + bool isLimitConnReached(Connection &conn); /* for handleConnection */ void readFromClient(Connection &conn, size_t &i, Parser &parser, HTTPRequest &request, HTTPResponse &response); diff --git a/src/ServerBlock.cpp b/src/ServerBlock.cpp index 2a667bc8..9052367c 100644 --- a/src/ServerBlock.cpp +++ b/src/ServerBlock.cpp @@ -39,7 +39,8 @@ bool ServerBlock::addDirective(std::string key, std::string &value, bool isLocat "cgi_path", "cgi_ext", "return", - "upload_path"}; + "upload_path", + "limit_conn"}; std::list validVar(var, var + sizeof(var) / sizeof(var[0])); if (std::find(validVar.begin(), validVar.end(), key) == validVar.end()) @@ -74,6 +75,8 @@ bool ServerBlock::addDirective(std::string key, std::string &value, bool isLocat setReturn(value, isLocation); else if (key == "upload_path") setUploadPath(value, isLocation); + else if (key == "limit_conn") + setLimitConn(value, isLocation); else if (key == "path" && isLocation) setLocationPath(value); @@ -96,6 +99,8 @@ void ServerBlock::deleteData() _directives._cgiPath.clear(); _directives._cgiExt.clear(); _directives._return.clear(); + _directives._uploadPath.clear(); + _directives._limit_conn = 0; } Directives ServerBlock::getDirectives() const @@ -175,6 +180,11 @@ std::string ServerBlock::getUploadPath() const return (_directives._uploadPath); } +size_t ServerBlock::getLimitConn() const +{ + return (_directives._limit_conn); +} + void ServerBlock::setListen(Listen str, bool isLocation) { if (!isLocation) @@ -283,6 +293,23 @@ void ServerBlock::setClientMaxBodySize(std::string &str, bool isLocation) throw("client_max_body_size not allowed in location block"); } +void ServerBlock::setLimitConn(std::string str, bool isLocation) +{ + if (strToInt(str) < 1) + throw("Invalid limit_conn"); + + size_t n = strToInt(str); + if (!isLocation) + { + if (_directives._limit_conn > 0) + throw("limit_conn already set"); + _directives._limit_conn = n; + } + else + throw("limit_conn not allowed in location block"); +} + + void ServerBlock::setAutoIndex(std::string &str, bool isLocation) { bool a; diff --git a/src/ServerBlock.hpp b/src/ServerBlock.hpp index fb5c8583..87732f6d 100644 --- a/src/ServerBlock.hpp +++ b/src/ServerBlock.hpp @@ -28,6 +28,7 @@ struct Directives _cgiExt.clear(); _return = ""; _uploadPath = ""; + _limit_conn = 0; _path = ""; } @@ -47,6 +48,7 @@ struct Directives std::string _cgiPath; std::string _return; std::string _uploadPath; + size_t _limit_conn; std::string _path; // only for location blocks }; @@ -76,6 +78,7 @@ class ServerBlock std::string getCgiPath() const; std::string getReturn() const; std::string getUploadPath() const; + size_t getLimitConn() const; // SETTERS void setListen(Listen str, bool isLocation); @@ -91,6 +94,7 @@ class ServerBlock void setCgiPath(std::string str, bool isLocation); void setReturn(std::string str, bool isLocation); void setUploadPath(std::string str, bool isLocation); + void setLimitConn(std::string str, bool isLocation); void setLocationPath(std::string str); // clear ServerBlock diff --git a/var/www.development_site/cgi-bin/duration_ts.cgi b/var/www.development_site/cgi-bin/duration_ts.cgi index 8573dee7..ff8181ae 100755 --- a/var/www.development_site/cgi-bin/duration_ts.cgi +++ b/var/www.development_site/cgi-bin/duration_ts.cgi @@ -4,7 +4,7 @@ import time from datetime import datetime # Define the duration of the counter in seconds -duration = 2 +duration = 5 # Print the HTTP header print("Content-Type: text/html") From 3a79f94743d3a94366eaec1a9e2b81326b3c496e Mon Sep 17 00:00:00 2001 From: dantol29 Date: Fri, 24 May 2024 11:44:53 +0200 Subject: [PATCH 14/17] docs(503): add docs about 503 --- docs/HTTP_codes.md | 6 +++++- include/webserv.hpp | 1 + src/Server.cpp | 2 -- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/HTTP_codes.md b/docs/HTTP_codes.md index b6bc41a5..0b1f8023 100644 --- a/docs/HTTP_codes.md +++ b/docs/HTTP_codes.md @@ -92,4 +92,8 @@ TODO (@Stefano maybe?) Send request with headers > 8KB ## 451 Unavailable For Legal Reasons -_not supported_ \ No newline at end of file +_not supported_ + +## 503 Service Unavailable +### How to trigger? +Set `limit_connn` directive and send more requests than written there \ No newline at end of file diff --git a/include/webserv.hpp b/include/webserv.hpp index d7f71d02..f2a4440f 100644 --- a/include/webserv.hpp +++ b/include/webserv.hpp @@ -17,6 +17,7 @@ #define SEND_BUFFER_SIZE 1024 * 100 // 100 KB #define BUFFER_SIZE 1025 +#define CGI_BUFFER_SIZE 100 // 100 B #define CGI_TIMEOUT_S 10 // 10 seconds #define CGI_POLL_TIMEOUT_MS 500 // 0.5 seconds #define CLIENT_POLL_TIMEOUT_MS 10000 // 10 seconds diff --git a/src/Server.cpp b/src/Server.cpp index ebbe5021..5dd8ac32 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -6,8 +6,6 @@ #include "EventManager.hpp" #include "signal.h" -#define CGI_BUFFER_SIZE 100 // 4 KB - Server::Server(const Config &config, EventManager &eventManager) : _config(config), _eventManager(eventManager) { _maxClients = 10; From 7035a30865ed78503f3eb541cdad60210d1aae57 Mon Sep 17 00:00:00 2001 From: dantol29 Date: Fri, 24 May 2024 12:09:47 +0200 Subject: [PATCH 15/17] tests(503, 504): added tests for 503 and 504 --- include/webserv.hpp | 6 +-- src/Server.cpp | 3 +- tests/error_codes.sh | 41 ++++++++++++++++++- .../cgi-bin/500seconds.cgi | 26 ++++++++++++ 4 files changed, 70 insertions(+), 6 deletions(-) create mode 100755 var/www.development_site/cgi-bin/500seconds.cgi diff --git a/include/webserv.hpp b/include/webserv.hpp index f2a4440f..568a4f81 100644 --- a/include/webserv.hpp +++ b/include/webserv.hpp @@ -18,10 +18,10 @@ #define SEND_BUFFER_SIZE 1024 * 100 // 100 KB #define BUFFER_SIZE 1025 #define CGI_BUFFER_SIZE 100 // 100 B -#define CGI_TIMEOUT_S 10 // 10 seconds +#define CGI_TIMEOUT_S 6 // 6 seconds #define CGI_POLL_TIMEOUT_MS 500 // 0.5 seconds -#define CLIENT_POLL_TIMEOUT_MS 10000 // 10 seconds -#define CLIENT_TIMEOUT_S 7 // 7 seconds +#define CLIENT_POLL_TIMEOUT_MS 12000 // 12 seconds +#define CLIENT_TIMEOUT_S 10 // 10 seconds #define CONFIG_FILE_DEFAULT_PATH "./conf/webserv_default.conf" #define RED "\033[1;31m" diff --git a/src/Server.cpp b/src/Server.cpp index 5dd8ac32..71b1cef7 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -313,7 +313,7 @@ void Server::buildResponse(Connection &conn, size_t &i, HTTPRequest &request, HT if (conn.getCGIHasTimedOut()) { Debug::log("CGI timed out", Debug::CGI); - response.setStatusCode(500, "Internal Server Error"); + response.setStatusCode(504, "Internal Server Error"); response.setIsCGI(false); } else @@ -743,7 +743,6 @@ void Server::acceptNewConnection(Connection &conn) else _connectionsPerIP[conn.getServerIp()] += 1; - std::cout << "Server IP: " << conn.getServerIp() << std::endl; newConnection.setServerPort(conn.getServerPort()); if (VERBOSE) { diff --git a/tests/error_codes.sh b/tests/error_codes.sh index 6099397d..3984702d 100755 --- a/tests/error_codes.sh +++ b/tests/error_codes.sh @@ -97,12 +97,51 @@ fi response=$(curl -s -o /dev/null -w "%{http_code}" -H "Host: www.development_site" http://127.0.0.1:8080/cgi-bin/duration_ts.cgi) if [ "$response" -eq 200 ]; then - echo -e "$GREEN www.development_site.com:8080: 200 $RESET" + echo -e "$GREEN www.development_site.com:8080: 200 $GREEN" +else + echo -e "$RED www.development_site.com:8080: $response $RESET" + is_error=true +fi + +response=$(curl -s -o /dev/null -w "%{http_code}" -H "Host: www.development_site" http://127.0.0.1:8080/cgi-bin/500seconds.cgi) + +if [ "$response" -eq 504 ]; then + echo -e "$GREEN www.development_site.com:8080: 504(Gateway Timeout) $GREEN" else echo -e "$RED www.development_site.com:8080: $response $RESET" is_error=true fi +urls=( + "http://127.0.0.1:8080/cgi-bin/duration_ts.cgi" + "http://127.0.0.1:8080/cgi-bin/duration_ts.cgi" + "http://127.0.0.1:8080/cgi-bin/duration_ts.cgi" + "http://127.0.0.1:8080/cgi-bin/duration_ts.cgi" +) + +# send 4 requests in parallel (limit in server block is 3, so the last request expects a 503 response) +expected_responses=(200 200 200 503) + +for i in "${!urls[@]}"; do + ( + response=$(curl -s -o /dev/null -w "%{http_code}" -H "Host: www.development_site" "${urls[$i]}") + if [ "$response" -eq "${expected_responses[$i]}" ]; then + echo -e "$GREEN www.development_site.com:8080: $response $GREEN" + else + echo -e "$RED www.development_site.com:8080: $response $GREEN" + is_error=true + fi + ) & + + # Add a delay of 1 second before the next iteration, except after the last request + if [ "$i" -lt $(( ${#urls[@]} - 1 )) ]; then + sleep 0.3 + fi +done + +# Wait for all background processes to finish +wait + if [ "$is_error" = true ]; then exit 1 fi diff --git a/var/www.development_site/cgi-bin/500seconds.cgi b/var/www.development_site/cgi-bin/500seconds.cgi new file mode 100755 index 00000000..44552e98 --- /dev/null +++ b/var/www.development_site/cgi-bin/500seconds.cgi @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 + +import time +from datetime import datetime + +# Define the duration of the counter in seconds +duration = 500 + +# Print the HTTP header +print("Content-Type: text/html") +print() + +# Print the start time as Unix timestamp +start_time = datetime.now().timestamp() +print(f"") +print(f"

Counter Script

") +print(f"

Start time: {start_time}

") + +# Counter loop +for i in range(duration): + time.sleep(1) # Wait for 1 second + +# Print the end time as Unix timestamp +end_time = datetime.now().timestamp() +print(f"

End time: {end_time}

") +print("") From 841eb65951650d89e2ea77e7145f798ae5fd7677 Mon Sep 17 00:00:00 2001 From: dantol29 Date: Fri, 24 May 2024 12:19:47 +0200 Subject: [PATCH 16/17] docs(HTTP codes): 503, 504, 500 --- docs/HTTP_codes.md | 17 +++++++++++++---- docs/config_file/config_file.md | 20 +++++++++++++++++++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/docs/HTTP_codes.md b/docs/HTTP_codes.md index 0b1f8023..0d4979cd 100644 --- a/docs/HTTP_codes.md +++ b/docs/HTTP_codes.md @@ -38,21 +38,21 @@ _not supported_ ## 411 Length Required ### How to trigger? -Send POST request without Content-Length header +Send POST request without `Content-Length` header ## 412 Precondition Failed _not supported_ ## 413 Payload Too Large ### How to trigger? -Send POST request bigger than client_max_body_size +Send POST request bigger than `client_max_body_size` ## 414 URI Too Long ### How to trigger? Send request with headers > 8KB ## 415 Unsupported Media Type -Send request to CGI that is not in cgi_ext directive +Send request to CGI that is not in `cgi_ext` directive ## 416 Range Not Satisfiable _not supported_ @@ -94,6 +94,15 @@ Send request with headers > 8KB ## 451 Unavailable For Legal Reasons _not supported_ +## 500 Internal Server Error +Launch CGI with error inside + ## 503 Service Unavailable ### How to trigger? -Set `limit_connn` directive and send more requests than written there \ No newline at end of file +Set `limit_connn` directive and send more requests than written there + +## 504 Gateway Timeout +### How to trigger? +Launch CGI that is executed longer than 5 seconds + +_13 supported errors_ \ No newline at end of file diff --git a/docs/config_file/config_file.md b/docs/config_file/config_file.md index 7c56f42b..6d7d9e5c 100644 --- a/docs/config_file/config_file.md +++ b/docs/config_file/config_file.md @@ -22,6 +22,8 @@ server { - cgi_path - cgi_ext - return +- upload_path +- limit_conn ### 1. LISTEN - Can be written multiple times per _server block_ @@ -118,11 +120,27 @@ server { ### 11. RETURN - Can be written only once per _server block_ - Redirects user to a certain URL -- is stored in the `std::string>` +- is stored in the `std::string` +- _OUR PROTECTION:_ + 1. no protection +- _DEFAULT VALUE_ + +### 12. UPLOAD_PATH +- Can be written only once per _server block_ +- Says where files should be uploaded to +- is stored in the `std::string` - _OUR PROTECTION:_ 1. no protection - _DEFAULT VALUE_ +### 13. LIMIT_CONN +- Can be written only once per _server block_ +- Controls the number of simultaneous connections +- is stored in the `size_t` +- _OUR PROTECTION:_ + 1. check if number is valid +- _DEFAULT VALUE_ + ## OPTIONAL? ### UPLOAD_PATH \ No newline at end of file From 7ed593e851480b88d410b45df3c1cd98ef866679 Mon Sep 17 00:00:00 2001 From: dantol29 Date: Fri, 24 May 2024 12:31:09 +0200 Subject: [PATCH 17/17] docs(http): list all implementde error codes --- docs/HTTP_codes.md | 65 +++++++++------------------------------------- 1 file changed, 12 insertions(+), 53 deletions(-) diff --git a/docs/HTTP_codes.md b/docs/HTTP_codes.md index 0d4979cd..543f6ea9 100644 --- a/docs/HTTP_codes.md +++ b/docs/HTTP_codes.md @@ -2,12 +2,6 @@ ### How to trigger? Send invalid HTTP request -## 401 Unauthorized -_not supported_ - -## 402 Payment Required -_not supported_ - ## 403 Forbidden ### How to trigger? Access file without permissions (TODO: @Leo) @@ -20,29 +14,14 @@ Access unexisting page ### How to trigger? Any request method besides GET, POST, DELETE -## 406 Not Acceptable -_not supported_ - -## 407 Proxy Authentication Required -_not supported_ - ## 408 Request Timeout ### How to trigger? Send a request with incomplete headers -## 409 Conflict -_not supported_ - -## 410 Gone -_not supported_ - ## 411 Length Required ### How to trigger? Send POST request without `Content-Length` header -## 412 Precondition Failed -_not supported_ - ## 413 Payload Too Large ### How to trigger? Send POST request bigger than `client_max_body_size` @@ -52,37 +31,11 @@ Send POST request bigger than `client_max_body_size` Send request with headers > 8KB ## 415 Unsupported Media Type +### How to trigger? Send request to CGI that is not in `cgi_ext` directive -## 416 Range Not Satisfiable -_not supported_ - -## 417 Expectation Failed -_not supported_ - ## 418 I'm a teapot -_not supported_ - -## 421 Misdirected Request -_not supported_ - -## 422 Unprocessable Content (WebDAV) -_not supported_ - -## 423 Locked (WebDAV) -_not supported_ - -## 424 Failed Dependency (WebDAV) -_not supported_ - -## 425 Too Early Experimental -_not supported_ - -## 426 Upgrade Required -TODO (@Someone) - -## 428 Precondition Required -_not supported_ +Would be nice to have ## 429 Too Many Requests TODO (@Stefano maybe?) @@ -91,12 +44,14 @@ TODO (@Stefano maybe?) ### How to trigger? Send request with headers > 8KB -## 451 Unavailable For Legal Reasons -_not supported_ - ## 500 Internal Server Error +### How to trigger? Launch CGI with error inside +## 501 Not Implemented +### How to trigger? +Send a request with unsupported HTTP method + ## 503 Service Unavailable ### How to trigger? Set `limit_connn` directive and send more requests than written there @@ -105,4 +60,8 @@ Set `limit_connn` directive and send more requests than written there ### How to trigger? Launch CGI that is executed longer than 5 seconds -_13 supported errors_ \ No newline at end of file +## 505 HTTP Version Not Supported +### How to trigger? +Send a request with invalid HTTP version(not HTTP/1.1) + +_16 supported errors_ \ No newline at end of file