diff --git a/Makefile b/Makefile index 6116405..dceb576 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: adjoly +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2024/10/25 16:09:27 by adjoly #+# #+# # -# Updated: 2025/01/21 13:13:53 by mmoussou ### ########.fr # +# Updated: 2025/02/03 16:43:32 by mmoussou ### ########.fr # # # # **************************************************************************** # @@ -18,6 +18,8 @@ CC = c++ OBJSDIR = obj/ +INCLUDES = ./includes + SRCS = $(shell find . -name '*.cpp') OBJS = $(addprefix $(OBJSDIR), $(SRCS:.cpp=.o)) @@ -38,12 +40,12 @@ endif all: $(NAME) $(NAME): $(OBJS) - @$(CC) $(FLAGS) -I . $(OBJS) -o $(NAME) + @$(CC) $(FLAGS) -I$(INCLUDES) $(OBJS) -o $(NAME) @printf "$(YELLOW)「✨」 feat($(NAME)): program compiled\n" $(OBJSDIR)%.o: %.cpp @mkdir -p $(@D) - @$(CC) $(FLAGS) -I . -c $< -o $@ + @$(CC) $(FLAGS) -I$(INCLUDES) -c $< -o $@ @printf "$(DELETE)$(GREEN)「🔨」 build($<): object compiled\n" clean: diff --git a/includes/requests/HttpRequest.hpp b/includes/requests/HttpRequest.hpp new file mode 100644 index 0000000..e828a51 --- /dev/null +++ b/includes/requests/HttpRequest.hpp @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* HttpRequest.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mmoussou headers; + std::string body; +}; + +HttpRequest parseRequest(const std::string &rawRequest); + +#endif diff --git a/includes/requests/HttpResponse.hpp b/includes/requests/HttpResponse.hpp new file mode 100644 index 0000000..f9784a0 --- /dev/null +++ b/includes/requests/HttpResponse.hpp @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* HttpResponse.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mmoussou _headers; + std::string _body; + +}; + +#endif diff --git a/src/webserv.cpp b/includes/requests/default.hpp similarity index 57% rename from src/webserv.cpp rename to includes/requests/default.hpp index b60c590..9584306 100644 --- a/src/webserv.cpp +++ b/includes/requests/default.hpp @@ -1,20 +1,26 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* webserv.cpp :+: :+: :+: */ +/* default.hpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: adjoly +#+ +:+ +#+ */ +/* By: mmoussou +#include +#include +#include #include -int main(int ac, char **av, char **env) { - (void)ac; - (void)av; - (void)env; - std::cout << "test" << std::endl; -} +#include "requests/HttpRequest.hpp" +#include "requests/HttpResponse.hpp" + +#endif diff --git a/index.html b/index.html new file mode 100644 index 0000000..89abca8 --- /dev/null +++ b/index.html @@ -0,0 +1,11 @@ + + + + +

evilge

+ + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..fb4b71b --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mmoussou +#include +#include +#include +#include +#include +#include +#include +#include + +#include "requests/default.hpp" + +#define PORT 8080 +#define BUFFER_SIZE 4096 + +int server_socket; + +void close_socket(int signal) +{ + close(server_socket); + exit(signal); +} + +int main() { + // handle ctrl-C to close server socket + if (signal(SIGINT, close_socket) == SIG_ERR) { + std::cerr << "Error registering signal handler!" << std::endl; + return 1; + } + + // create a socket + server_socket = socket(AF_INET, SOCK_STREAM, 0); + if (server_socket == -1) { + std::cerr << "Failed to create socket" << std::endl; + return 1; + } + + // prepare the server address + sockaddr_in server_address; + std::memset(&server_address, 0, sizeof(server_address)); + server_address.sin_family = AF_INET; + server_address.sin_addr.s_addr = INADDR_ANY; + server_address.sin_port = htons(PORT); + + // bind the socket to the address + if (bind(server_socket, (sockaddr*)&server_address, sizeof(server_address)) == -1) { + std::cerr << "Failed to bind socket" << std::endl; + return 1; + } + + // listen for incoming connections + if (listen(server_socket, 5) == -1) { + std::cerr << "Failed to listen on socket" << std::endl; + return 1; + } + + std::cout << "Server is listening on port " << PORT << std::endl; + + while (true) { + // accept an incoming connection + sockaddr_in client_address; + socklen_t client_address_len = sizeof(client_address); + int client_socket = accept(server_socket, (sockaddr*)&client_address, &client_address_len); + if (client_socket == -1) { + std::cerr << "Failed to accept connection" << std::endl; + continue; + } + + // receive the HTTP request + char buffer[BUFFER_SIZE]; + std::memset(buffer, 0, BUFFER_SIZE); + ssize_t bytes_received = recv(client_socket, buffer, BUFFER_SIZE - 1, 0); + if (bytes_received == -1) { + std::cerr << "Failed to receive request" << std::endl; + close(client_socket); + continue; + } + + // parse the request + std::string received_data(buffer, bytes_received); + HttpRequest request = parseRequest(received_data); + + std::cout << "Received " << request.method << " request for " << request.target << std::endl; + + + // handle the request + if (request.method == "GET") + { + HttpResponse response(request); + send(client_socket, response.str().c_str(), response.str().length(), 0); + } + else + { + std::string response = "HTTP/1.1 501 Not Implemented\r\nContent-Type: text/html\r\n\r\n

501 Not Implemented

"; + send(client_socket, response.c_str(), response.length(), 0); + } + + close(client_socket); + } + + close(server_socket); + return 0; +} diff --git a/src/requests_handling/HttpRequests.cpp b/src/requests_handling/HttpRequests.cpp new file mode 100644 index 0000000..74fc0a3 --- /dev/null +++ b/src/requests_handling/HttpRequests.cpp @@ -0,0 +1,55 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* HttpRequests.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mmoussou > request.method >> request.target >> request.protocol; + request.target.insert(request.target.begin(), '.'); + } + + while (std::getline(stream, line) && line != "\r") + { + size_t delimiter_index = line.find(':'); + if (delimiter_index != std::string::npos) + { + std::string key = line.substr(0, delimiter_index); + std::string value = line.substr(delimiter_index + 2); + request.headers[key] = value; + } + } + + std::ostringstream body_stream; + while (std::getline(stream, line)) + body_stream << line << "\n"; + request.body = body_stream.str(); + + std::cout << "method: " << request.method << std::endl; + std::cout << "target: " << request.target << std::endl; + std::cout << "protocol: " << request.protocol << std::endl; + std::cout << std::endl; + std::cout << "-- headers --" << std::endl; + for (std::map::const_iterator it = request.headers.begin(); it != request.headers.end(); ++it) + std::cout << it->first << ": " << it->second << std::endl; + std::cout << std::endl; + std::cout << "-- body --" << std::endl << request.body << std::endl; + + return request; +} diff --git a/src/requests_handling/HttpResponse.cpp b/src/requests_handling/HttpResponse.cpp new file mode 100644 index 0000000..ea412eb --- /dev/null +++ b/src/requests_handling/HttpResponse.cpp @@ -0,0 +1,69 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* HttpResponse.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mmoussou _headers; +std::string _body;*/ + +HttpResponse::HttpResponse(const HttpRequest &request): _protocol(request.protocol) +{ + std::ifstream file(request.target.c_str(), std::ios::binary); + if (file) + { + this->_status_code = 200; + this->_status_text = "OK"; + this->_headers["Content-Type"] = "text/html"; + this->_body = std::string((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + } + else + { + this->_status_code = 404; + this->_status_text = "Not Found"; + this->_headers["Content-Type"] = "text/html"; + this->_body = "nuh uh, get 404'd >:D"; + } +} + +HttpResponse::HttpResponse(const HttpResponse &cpy) +{ + (void) cpy; +} + +HttpResponse::~HttpResponse(void) +{ +} + +HttpResponse &HttpResponse::operator=(const HttpResponse &cpy) +{ + (void) cpy; + return (*this); +} + +std::string HttpResponse::str(void) const +{ + std::ostringstream response; + + response << this->_protocol << " " << this->_status_code << " " << this->_status_text; + response << "\r\n"; + + for (std::map::const_iterator it = this->_headers.begin(); it != this->_headers.end(); ++it) + response << it->first << ": " << it->second << "\r\n"; + + response << "\r\n"; + response << this->_body; + + return (response.str()); +}