From f2f1c3e2aec7d5d9792b1db01147fdae687dda4b Mon Sep 17 00:00:00 2001 From: __mo_san__ <50895527+M0-san@users.noreply.github.com> Date: Wed, 17 Nov 2021 16:08:05 +0100 Subject: [PATCH 01/24] Update README.md add infos about server block --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index 87eeac7..fb4355e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,39 @@ # webserv #### Serer Block Configurations + - A virtual server is defined by a server directive. - A server block is a subset of servers’s configuration that defines a virtual server used to handle requests of a defined type. + - + ``` + server { + # Server configuration + } + ``` + - It is possible to add multiple server directives into the http context to define multiple virtual servers. + ``` + server { + # Server configuration + } + + server { + # Other Server configuration + } + ``` + + - The server configuration block usually includes a listen directive to specify the IP address and port on which the server listens for requests. + ``` + server { + # Server configuration + listen 127.0.0.1:8080 + + # Or + host 127.0.0.1 + port 8080 + } + ``` + - If a port is omitted, the standard port is used. Likewise, if an address is omitted, the server listens on all addresses. + - If the listen directive is not included at all, the “standard” port is 80/tcp and the “default” port is 8000/tcp, depending on superuser privileges. + - If there are several servers that match the IP address and port of the request, the server tests the request’s Host header field against the server_name directives in the server blocks. - A location block lives within a server block and is used to define how Nginx should handle requests for different resources and URIs for the parent server. #### How Nginx Decides Which Server Block Will Handle a Request - From 39de8f0b130672135bf34c422ad4d8a8a2c5d59b Mon Sep 17 00:00:00 2001 From: __mo_san__ <50895527+M0-san@users.noreply.github.com> Date: Wed, 17 Nov 2021 16:08:30 +0100 Subject: [PATCH 02/24] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fb4355e..ec4d2d9 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ``` - The server configuration block usually includes a listen directive to specify the IP address and port on which the server listens for requests. - ``` + ``` server { # Server configuration listen 127.0.0.1:8080 From 803c7cf883d7108be8252fb7b47730391ddf1162 Mon Sep 17 00:00:00 2001 From: __mo_san__ <50895527+M0-san@users.noreply.github.com> Date: Wed, 17 Nov 2021 16:11:03 +0100 Subject: [PATCH 03/24] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ec4d2d9..ae5f34f 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,8 @@ ``` - If a port is omitted, the standard port is used. Likewise, if an address is omitted, the server listens on all addresses. - If the listen directive is not included at all, the “standard” port is 80/tcp and the “default” port is 8000/tcp, depending on superuser privileges. - - If there are several servers that match the IP address and port of the request, the server tests the request’s Host header field against the server_name directives in the server blocks. + - If there are several servers that match the IP address and port of the request, the server tests the request’s Host header field against the server_name directives in the server blocks. + - If the Host header field does not match a server name, should routes the request to the default server for the port on which the request arrived. The default server is the first one listed in the config file, unless you include the default_server parameter to the listen directive to explicitly designate a server as the default. - A location block lives within a server block and is used to define how Nginx should handle requests for different resources and URIs for the parent server. #### How Nginx Decides Which Server Block Will Handle a Request - From 69e9cf0965c7fa2f3b843e0b16da0db887b055b8 Mon Sep 17 00:00:00 2001 From: __mo_san__ <50895527+M0-san@users.noreply.github.com> Date: Wed, 17 Nov 2021 16:39:46 +0100 Subject: [PATCH 04/24] Update README.md --- README.md | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ae5f34f..d369726 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,52 @@ - If the listen directive is not included at all, the “standard” port is 80/tcp and the “default” port is 8000/tcp, depending on superuser privileges. - If there are several servers that match the IP address and port of the request, the server tests the request’s Host header field against the server_name directives in the server blocks. - If the Host header field does not match a server name, should routes the request to the default server for the port on which the request arrived. The default server is the first one listed in the config file, unless you include the default_server parameter to the listen directive to explicitly designate a server as the default. - - A location block lives within a server block and is used to define how Nginx should handle requests for different resources and URIs for the parent server. + + ### Serving Static Content + + An important web server task is serving out files (such as images or static HTML pages). You will implement an example where, depending on the request, files will be served from different local directories: /data/www (which may contain HTML files) and /data/images (containing images). This will require editing of the configuration file and setting up of a server block inside the http block with two location blocks. + + First, create the /data/www directory and put an index.html file with any text content into it and create the /data/images directory and place some images in it. + + Next, open the configuration file. The default configuration file already includes several examples of the server block, mostly commented out. For now comment out all such blocks and start a new server block: +``` +http { + server { + } +} +``` +Generally, the configuration file may include several server blocks distinguished by ports on which they listen to and by server names. Once nginx decides which server processes a request, it tests the URI specified in the request’s header against the parameters of the location directives defined inside the server block. + +Add the following location block to the server block: +``` +location / { + root /data/www; +} +``` +This location block specifies the “/” prefix compared with the URI from the request. For matching requests, the URI will be added to the path specified in the root directive, that is, to /data/www, to form the path to the requested file on the local file system. If there are several matching location blocks nginx selects the one with the longest prefix. The location block above provides the shortest prefix, of length one, and so only if all other location blocks fail to provide a match, this block will be used. + +Next, add the second location block: +``` +location /images/ { + root /data; +} +``` +It will be a match for requests starting with /images/ (location / also matches such requests, but has shorter prefix). + +The resulting configuration of the server block should look like this: +``` +server { + location / { + root /data/www; + } + + location /images/ { + root /data; + } +} +``` + +This is already a working configuration of a server that listens on the standard port 80 and is accessible on the local machine at http://localhost/. In response to requests with URIs starting with /images/, the server will send files from the /data/images directory. For example, in response to the http://localhost/images/example.png request nginx will send the /data/images/example.png file. If such file does not exist, nginx will send a response indicating the 404 error. Requests with URIs not starting with /images/ will be mapped onto the /data/www directory. For example, in response to the http://localhost/some/example.html request nginx will send the /data/www/some/example.html file. + #### How Nginx Decides Which Server Block Will Handle a Request - From 607baab8f321b3ac37f31d29b57a5ce0a5dc5754 Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Fri, 19 Nov 2021 19:06:24 +0100 Subject: [PATCH 05/24] new branch --- parser/parser.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/parser/parser.hpp b/parser/parser.hpp index 4f1f930..c4ae16a 100644 --- a/parser/parser.hpp +++ b/parser/parser.hpp @@ -71,6 +71,7 @@ struct ServerConfig { std::vector _location; + }; int getDirective(std::string const &token); From f63a229122827d265d2cc0fb2d83b55da3623bc7 Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Fri, 19 Nov 2021 21:48:46 +0100 Subject: [PATCH 06/24] done implementing default location --- Makefile | 12 +++++++++ hello.html | 9 +++++++ includes/location.hpp | 14 ++++++++++ includes/response.hpp | 20 ++++++++++++++ index.html | 9 +++++++ main.cpp | 54 ++++++++++++-------------------------- response.html | 9 +++++++ src/response.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 150 insertions(+), 38 deletions(-) create mode 100644 Makefile create mode 100644 hello.html create mode 100644 includes/location.hpp create mode 100644 includes/response.hpp create mode 100644 index.html create mode 100644 response.html create mode 100644 src/response.cpp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6facba4 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +SRC = main.cpp src/response.cpp +CMP = clang++ -std=c++98 +FLAGS = -Wall -Wextra -Werror -fsanitize=address -g3 +NAME = a.out +all : $(NAME) + +$(NAME): + $(CMP) $(FLAGS) $(SRC) -o a.out + +clean: + rm a.out +re: clean all \ No newline at end of file diff --git a/hello.html b/hello.html new file mode 100644 index 0000000..21ab4cd --- /dev/null +++ b/hello.html @@ -0,0 +1,9 @@ + + + + hello + + +

This is an example of a simple HTML page with one paragraph.

+ + \ No newline at end of file diff --git a/includes/location.hpp b/includes/location.hpp new file mode 100644 index 0000000..cdc9b30 --- /dev/null +++ b/includes/location.hpp @@ -0,0 +1,14 @@ +#pragma once +#include +#include + +class Location +{ + public: + Location(std::string const& path, std::vector const& index): _path(path), _index(index){} + std::string const& getPath(void) const { return _path; } + std::vector getIndex(void) const { return _index; } + private: + std::string _path; + std::vector _index; +}; \ No newline at end of file diff --git a/includes/response.hpp b/includes/response.hpp new file mode 100644 index 0000000..bd8b3b8 --- /dev/null +++ b/includes/response.hpp @@ -0,0 +1,20 @@ +#pragma once +# include +# include +# include +# include "location.hpp" + +class Response +{ + public: + Response(void); + Response(Response const&); + Response& operator=(Response const&); + void Get_request(std::string const&, Location const&, std::string const&); + std::string const& get_response(void) const; + size_t get_error(void) const; + private: + void _default_location(std::string const&, Location const&, std::string const&); + std::string _response; + size_t _error; +}; \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..75c29b0 --- /dev/null +++ b/index.html @@ -0,0 +1,9 @@ + + + + Example + + +

This is an example of a simple HTML page with one paragraph.

+ + \ No newline at end of file diff --git a/main.cpp b/main.cpp index 3dc2264..c0be054 100644 --- a/main.cpp +++ b/main.cpp @@ -1,41 +1,19 @@ -#include -#include -#include -#include -#include -#include -#include -#include "parser/parser.hpp" -#include "includes/request.hpp" -#include "includes/utility.hpp" - - -void testRequest() { - Request request; - std::ifstream ifs; - ifs.open("./request", std::ios_base::in); - if (ifs.is_open()) { - std::stringstream ss; - std::string line; - while (std::getline(ifs, line)) - ss << line << std::endl; - - request.parseRequest(ss); - auto it = request.getMap().begin(); - - for(; it != request.getMap().end(); ++it) { - std::cout << it->first << " "; - for (int i = 0; i < it->second.size(); ++i) - std::cout << it->second[i] << " "; - std::cout << std::endl; - } - } -} - - -int main() { - auto res = performParsing(); - std::cout << res << std::endl; +#include "includes/response.hpp" +#include "includes/location.hpp" + +int main() +{ + std::vector index; + index.push_back("file.html"); + index.push_back("index.html"); + Location loc("/", index); + Response res; + + res.Get_request("/Users/mamoussa/Desktop/42/webserv", loc, ""); + if (!res.get_error()) + std::cout << res.get_response(); + else + std::cout << "file not found" << std::endl; return EXIT_SUCCESS; } diff --git a/response.html b/response.html new file mode 100644 index 0000000..75c29b0 --- /dev/null +++ b/response.html @@ -0,0 +1,9 @@ + + + + Example + + +

This is an example of a simple HTML page with one paragraph.

+ + \ No newline at end of file diff --git a/src/response.cpp b/src/response.cpp new file mode 100644 index 0000000..39fb563 --- /dev/null +++ b/src/response.cpp @@ -0,0 +1,61 @@ +#include "../includes/response.hpp" +#include "../includes/location.hpp" + + +Response::Response(void): _response(""), _error(0){} +Response::Response(Response const& x) { *this = x; } +Response& Response::operator=(Response const& x) +{ + _response = x._response; + _error = x._error; + return *this; +} +void Response::Get_request(std::string const& root, Location const& loc, std::string const& uri) +{ + /* + * if the location is the @default location then we should check the type of the uri, is it a directory or a file + * and if it's a direcotry then we should check if it containes one of the names in the index directive, then we should return + * it's content, otherwise we should check if the autoindex it set to on means that we should list all the files in that directory + * if non of the prev condition is true then we should return an error + */ + if (loc.getPath() == "/") + _default_location(root, loc, uri); +} + +void Response::_default_location(std::string const& root, Location const& loc, std::string const& uri) +{ + std::string const full_path(root + '/' + uri); + std::vector const index = loc.getIndex(); + std::ifstream file; + std::string line; + + // first lets search if the location contains the uri as one of its index names + if (uri.empty()) + { + for (size_t i = 0; i < index.size(); ++i) + { + file.open(root + '/' + index[i]); + if (file.is_open()) + break; + } + } + else + file.open(full_path); + // if the file is good we will start reading its content + if (!file.is_open() || !file.good()) + { + _error = 404; + return; + } + while (!file.eof()) + { + std::getline(file, line); + if (!file.eof()) + line += '\n'; + _response += line; + } + file.close(); +} + +std::string const& Response::get_response(void) const { return _response; } +size_t Response::get_error(void) const { return _error; } \ No newline at end of file From 1660269e6a85dd20829ea2587d55e0eae893a736 Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Fri, 19 Nov 2021 22:45:12 +0100 Subject: [PATCH 07/24] added headers seter --- src/response.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/response.cpp b/src/response.cpp index 39fb563..0b08488 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -28,6 +28,8 @@ void Response::_default_location(std::string const& root, Location const& loc, s std::vector const index = loc.getIndex(); std::ifstream file; std::string line; + std::string tmp_resp; + size_t content_counter(0); // first lets search if the location contains the uri as one of its index names if (uri.empty()) @@ -50,12 +52,32 @@ void Response::_default_location(std::string const& root, Location const& loc, s while (!file.eof()) { std::getline(file, line); + content_counter += line.size(); if (!file.eof()) + { line += '\n'; - _response += line; + content_counter++; + } + tmp_resp += line; } + _set_headers(200, "OK", content_counter); + _response += tmp_resp; file.close(); } +void Response::_set_headers(size_t status_code, std::string const& message, size_t content_length) +{ + time_t rawtime; + + time (&rawtime); + _response += "HTTP/1.1 " + std::to_string(status_code) + " " + message + '\n'; + _response += "Date: " + std::string(ctime(&rawtime)); + _response += "Server: webserver\n"; + _response += "Content-Length: " + std::to_string(content_length) + '\n'; + _response += "Content-Type: \n"; + _response += "Connection: close\n"; + _response += '\n'; +} + std::string const& Response::get_response(void) const { return _response; } size_t Response::get_error(void) const { return _error; } \ No newline at end of file From bef8a38978215e98725f0395d4c8f8c88b5ec4c6 Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Sat, 20 Nov 2021 23:28:48 +0100 Subject: [PATCH 08/24] added error pages --- error_pages/403.html | 15 ++++++ error_pages/404.html | 15 ++++++ file.json | 1 + hello.html | 3 -- includes/location.hpp | 1 + includes/response.hpp | 27 ++++++++-- index.html | 0 main.cpp | 17 +++--- src/response.cpp | 119 ++++++++++++++++++++++++++++-------------- 9 files changed, 142 insertions(+), 56 deletions(-) create mode 100644 error_pages/403.html create mode 100644 error_pages/404.html create mode 100644 file.json mode change 100644 => 100755 index.html diff --git a/error_pages/403.html b/error_pages/403.html new file mode 100644 index 0000000..c860cb4 --- /dev/null +++ b/error_pages/403.html @@ -0,0 +1,15 @@ + + + + 403 Forbidden + + + +
+

403 Forbidden

+
+
+
nginx/1.21.4
+ + + \ No newline at end of file diff --git a/error_pages/404.html b/error_pages/404.html new file mode 100644 index 0000000..0d9dec6 --- /dev/null +++ b/error_pages/404.html @@ -0,0 +1,15 @@ + + + + 404 Not Found + + + +
+

404 Not Found

+
+
+
nginx/1.21.4
+ + + \ No newline at end of file diff --git a/file.json b/file.json new file mode 100644 index 0000000..978d70e --- /dev/null +++ b/file.json @@ -0,0 +1 @@ +{"name":"John", "age":30, "car":null} \ No newline at end of file diff --git a/hello.html b/hello.html index 21ab4cd..bfd56b7 100644 --- a/hello.html +++ b/hello.html @@ -3,7 +3,4 @@ hello - -

This is an example of a simple HTML page with one paragraph.

- \ No newline at end of file diff --git a/includes/location.hpp b/includes/location.hpp index cdc9b30..41ebe3d 100644 --- a/includes/location.hpp +++ b/includes/location.hpp @@ -5,6 +5,7 @@ class Location { public: + Location(){} Location(std::string const& path, std::vector const& index): _path(path), _index(index){} std::string const& getPath(void) const { return _path; } std::vector getIndex(void) const { return _index; } diff --git a/includes/response.hpp b/includes/response.hpp index bd8b3b8..5181f00 100644 --- a/includes/response.hpp +++ b/includes/response.hpp @@ -2,19 +2,36 @@ # include # include # include +# include +# include +# include +# include +# include # include "location.hpp" class Response { public: Response(void); + Response(std::string const&, Location const&, std::string const&, std::string const&); Response(Response const&); Response& operator=(Response const&); - void Get_request(std::string const&, Location const&, std::string const&); + ~Response(void); + public: + void Get_request(void); std::string const& get_response(void) const; - size_t get_error(void) const; private: - void _default_location(std::string const&, Location const&, std::string const&); - std::string _response; - size_t _error; + bool _default_location(void); + void _set_headers(size_t, std::string const&, size_t, std::string const&); + void _fill_response(std::string const&, size_t, std::string const&); + bool _file_is_good(void); + private: + std::string _response; + std::ifstream _file; + std::string _file_path; + Location _loc; + std::string const _root; + std::string const _uri; + std::string const _error_pages; + std::map _type; }; \ No newline at end of file diff --git a/index.html b/index.html old mode 100644 new mode 100755 diff --git a/main.cpp b/main.cpp index c0be054..79326f4 100644 --- a/main.cpp +++ b/main.cpp @@ -1,19 +1,18 @@ #include "includes/response.hpp" #include "includes/location.hpp" +#include +#include +#include int main() { std::vector index; - index.push_back("file.html"); + index.push_back("hello.html"); index.push_back("index.html"); - Location loc("/", index); - Response res; - - res.Get_request("/Users/mamoussa/Desktop/42/webserv", loc, ""); - if (!res.get_error()) - std::cout << res.get_response(); - else - std::cout << "file not found" << std::endl; + Location loc("/hello.html", index); + Response res("/Users/mamoussa/Desktop/42/webserv", loc, "hello.html", "/Users/mamoussa/Desktop/42/webserv/error_pages"); + res.Get_request(); + std::cout << res.get_response(); return EXIT_SUCCESS; } diff --git a/src/response.cpp b/src/response.cpp index 0b08488..cc3281e 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -2,15 +2,26 @@ #include "../includes/location.hpp" -Response::Response(void): _response(""), _error(0){} +Response::Response(void): _response(""), _loc() +, _root(""), _uri(""), _error_pages(""){} + +Response::Response(std::string const& root, Location const& loc +, std::string const& uri, std::string const& error_pages): _loc(loc), _root(root) +, _uri(uri), _error_pages(error_pages) +{ + _type.insert(std::make_pair("json", "application")); + _type.insert(std::make_pair("html", "text")); +} + Response::Response(Response const& x) { *this = x; } +Response::~Response(void) { _file.close(); } Response& Response::operator=(Response const& x) { _response = x._response; - _error = x._error; return *this; } -void Response::Get_request(std::string const& root, Location const& loc, std::string const& uri) + +void Response::Get_request(void) { /* * if the location is the @default location then we should check the type of the uri, is it a directory or a file @@ -18,54 +29,48 @@ void Response::Get_request(std::string const& root, Location const& loc, std::st * it's content, otherwise we should check if the autoindex it set to on means that we should list all the files in that directory * if non of the prev condition is true then we should return an error */ - if (loc.getPath() == "/") - _default_location(root, loc, uri); + if (_loc.getPath() == "/") + { + if (!_default_location()) // if we had an error while trying to open the file location we should return back + return; + } + if (_file_path.empty()) + { + if (!_file_is_good()) + return; + } + _fill_response(_file_path, 200, "OK"); // if all good than we should fill the response with 200 status code } -void Response::_default_location(std::string const& root, Location const& loc, std::string const& uri) +bool Response::_default_location(void) { - std::string const full_path(root + '/' + uri); - std::vector const index = loc.getIndex(); - std::ifstream file; - std::string line; - std::string tmp_resp; - size_t content_counter(0); + std::vector const index = _loc.getIndex(); + bool found(false); // first lets search if the location contains the uri as one of its index names - if (uri.empty()) + if (_uri.empty()) { for (size_t i = 0; i < index.size(); ++i) { - file.open(root + '/' + index[i]); - if (file.is_open()) + _file_path = _root + '/' + index[i]; + if (!(found = _file_is_good()) && errno != 2) + { + _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); + return false; + } + else if (found) break; } - } - else - file.open(full_path); - // if the file is good we will start reading its content - if (!file.is_open() || !file.good()) - { - _error = 404; - return; - } - while (!file.eof()) - { - std::getline(file, line); - content_counter += line.size(); - if (!file.eof()) + if (!found) { - line += '\n'; - content_counter++; + _fill_response(_error_pages + '/' + "404.html", 404, "Not found"); + return false; } - tmp_resp += line; } - _set_headers(200, "OK", content_counter); - _response += tmp_resp; - file.close(); + return true; } -void Response::_set_headers(size_t status_code, std::string const& message, size_t content_length) +void Response::_set_headers(size_t status_code, std::string const& message, size_t content_length, std::string const& path) { time_t rawtime; @@ -74,10 +79,46 @@ void Response::_set_headers(size_t status_code, std::string const& message, size _response += "Date: " + std::string(ctime(&rawtime)); _response += "Server: webserver\n"; _response += "Content-Length: " + std::to_string(content_length) + '\n'; - _response += "Content-Type: \n"; + _response += "Content-Type: " + _type[path.substr(path.find_last_of(".") + 1)] + '/' + + path.substr(path.find_last_of(".") + 1) + '\n'; _response += "Connection: close\n"; _response += '\n'; } -std::string const& Response::get_response(void) const { return _response; } -size_t Response::get_error(void) const { return _error; } \ No newline at end of file +void Response::_fill_response(std::string const& path, size_t status_code, std::string const& message) +{ + std::string line; + std::string tmp_resp; + size_t content_counter(0); + + _file.open(path); + while (!_file.eof()) + { + std::getline(_file, line); + content_counter += line.size(); + if (!_file.eof()) + { + line += '\n'; + content_counter++; + } + tmp_resp += line; + } + // set all the needed response header + _set_headers(status_code, message, content_counter, path); + _response += tmp_resp; +} + +bool Response::_file_is_good(void) +{ + _file_path = _root + '/' + _uri; + if (open(_file_path.c_str(), O_RDONLY) < 0) + { + if (errno == 2) + _fill_response(_error_pages + '/' + "404.html", 404, "Not Found"); + else + _fill_response(_error_pages + '/' + "403.html", 403, "Forbidden"); + return false; + } + return true; +} +std::string const& Response::get_response(void) const { return _response; } \ No newline at end of file From ad67afaf43e9b2cea0627a11cc480fe17e6be8fb Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Sun, 21 Nov 2021 01:37:14 +0100 Subject: [PATCH 09/24] added directory check --- includes/location.hpp | 6 ++++-- includes/response.hpp | 10 ++++++---- main.cpp | 4 ++-- src/hello.html | 6 ++++++ src/response.cpp | 36 +++++++++++++++++++++++++++++------- 5 files changed, 47 insertions(+), 15 deletions(-) create mode 100644 src/hello.html diff --git a/includes/location.hpp b/includes/location.hpp index 41ebe3d..c7d4643 100644 --- a/includes/location.hpp +++ b/includes/location.hpp @@ -9,7 +9,9 @@ class Location Location(std::string const& path, std::vector const& index): _path(path), _index(index){} std::string const& getPath(void) const { return _path; } std::vector getIndex(void) const { return _index; } + std::string const& getAutoIndex(void) const { return _autoIndex;} private: - std::string _path; - std::vector _index; + std::string _path; + std::vector _index; + std::string _autoIndex; }; \ No newline at end of file diff --git a/includes/response.hpp b/includes/response.hpp index 5181f00..ec3fdb4 100644 --- a/includes/response.hpp +++ b/includes/response.hpp @@ -5,6 +5,7 @@ # include # include # include +# include # include # include # include "location.hpp" @@ -24,14 +25,15 @@ class Response bool _default_location(void); void _set_headers(size_t, std::string const&, size_t, std::string const&); void _fill_response(std::string const&, size_t, std::string const&); - bool _file_is_good(void); + bool _file_is_good(bool); + bool _is_dir(void) const; private: std::string _response; std::ifstream _file; std::string _file_path; Location _loc; - std::string const _root; - std::string const _uri; - std::string const _error_pages; + std::string _root; + std::string _uri; + std::string _error_pages; std::map _type; }; \ No newline at end of file diff --git a/main.cpp b/main.cpp index 79326f4..f314ce9 100644 --- a/main.cpp +++ b/main.cpp @@ -9,8 +9,8 @@ int main() std::vector index; index.push_back("hello.html"); index.push_back("index.html"); - Location loc("/hello.html", index); - Response res("/Users/mamoussa/Desktop/42/webserv", loc, "hello.html", "/Users/mamoussa/Desktop/42/webserv/error_pages"); + Location loc("/", index); + Response res("/Users/mamoussa/Desktop/42/webserv", loc, "src", "/Users/mamoussa/Desktop/42/webserv/error_pages"); res.Get_request(); std::cout << res.get_response(); return EXIT_SUCCESS; diff --git a/src/hello.html b/src/hello.html new file mode 100644 index 0000000..bfd56b7 --- /dev/null +++ b/src/hello.html @@ -0,0 +1,6 @@ + + + + hello + + \ No newline at end of file diff --git a/src/response.cpp b/src/response.cpp index cc3281e..8499d50 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -29,14 +29,21 @@ void Response::Get_request(void) * it's content, otherwise we should check if the autoindex it set to on means that we should list all the files in that directory * if non of the prev condition is true then we should return an error */ + if (_is_dir()) // if the uri is a dir, then we should check if we have a autoindex=on so we should list all the files and return, else we should join it whith the root + { + if (_loc.getAutoIndex() == "on") + return; + _root += '/' + _uri; + _uri.clear(); + } if (_loc.getPath() == "/") { if (!_default_location()) // if we had an error while trying to open the file location we should return back return; } - if (_file_path.empty()) + if (_file_path.empty()) // if we get an empty path than we didn't found the file we are searching for in the index directive or we are not in the default location { - if (!_file_is_good()) + if (!_file_is_good(true)) return; } _fill_response(_file_path, 200, "OK"); // if all good than we should fill the response with 200 status code @@ -53,7 +60,7 @@ bool Response::_default_location(void) for (size_t i = 0; i < index.size(); ++i) { _file_path = _root + '/' + index[i]; - if (!(found = _file_is_good()) && errno != 2) + if (!(found = _file_is_good(false)) && errno != 2) // if the file exists but we don't have the permissions to read from it { _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); return false; @@ -70,6 +77,20 @@ bool Response::_default_location(void) return true; } +bool Response::_is_dir(void) const +{ + struct stat s; + + if (!lstat(_uri.c_str(), &s)) + { + if (S_ISDIR(s.st_mode)) + return true; + else + return false; + } + return false; +} + void Response::_set_headers(size_t status_code, std::string const& message, size_t content_length, std::string const& path) { time_t rawtime; @@ -108,14 +129,15 @@ void Response::_fill_response(std::string const& path, size_t status_code, std:: _response += tmp_resp; } -bool Response::_file_is_good(void) +bool Response::_file_is_good(bool fill_resp) { - _file_path = _root + '/' + _uri; + if (_file_path.empty()) + _file_path = _root + '/' + _uri; if (open(_file_path.c_str(), O_RDONLY) < 0) { - if (errno == 2) + if (errno == 2 && fill_resp) _fill_response(_error_pages + '/' + "404.html", 404, "Not Found"); - else + else if (fill_resp) _fill_response(_error_pages + '/' + "403.html", 403, "Forbidden"); return false; } From 401c54e6c87a0f92a814a94e25fb91db0b47c3fc Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Sun, 21 Nov 2021 02:36:17 +0100 Subject: [PATCH 10/24] Added check for allowed methods --- includes/location.hpp | 5 ++++- main.cpp | 4 +++- src/file.html | 0 src/response.cpp | 21 ++++++++++++++------- 4 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 src/file.html diff --git a/includes/location.hpp b/includes/location.hpp index c7d4643..60f5eca 100644 --- a/includes/location.hpp +++ b/includes/location.hpp @@ -6,12 +6,15 @@ class Location { public: Location(){} - Location(std::string const& path, std::vector const& index): _path(path), _index(index){} + Location(std::string const& path, std::vector const& index, std::vector const& allowed): + _path(path), _index(index), _allowed_methods(allowed){} std::string const& getPath(void) const { return _path; } std::vector getIndex(void) const { return _index; } + std::vector getAllowedMethods(void) const { return _allowed_methods; } std::string const& getAutoIndex(void) const { return _autoIndex;} private: std::string _path; std::vector _index; + std::vector _allowed_methods; std::string _autoIndex; }; \ No newline at end of file diff --git a/main.cpp b/main.cpp index f314ce9..c564718 100644 --- a/main.cpp +++ b/main.cpp @@ -7,9 +7,11 @@ int main() { std::vector index; + std::vector allowed; index.push_back("hello.html"); index.push_back("index.html"); - Location loc("/", index); + allowed.push_back("POST"); + Location loc("/", index, allowed); Response res("/Users/mamoussa/Desktop/42/webserv", loc, "src", "/Users/mamoussa/Desktop/42/webserv/error_pages"); res.Get_request(); std::cout << res.get_response(); diff --git a/src/file.html b/src/file.html new file mode 100644 index 0000000..e69de29 diff --git a/src/response.cpp b/src/response.cpp index 8499d50..3ca5bb9 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -23,19 +23,26 @@ Response& Response::operator=(Response const& x) void Response::Get_request(void) { - /* - * if the location is the @default location then we should check the type of the uri, is it a directory or a file - * and if it's a direcotry then we should check if it containes one of the names in the index directive, then we should return - * it's content, otherwise we should check if the autoindex it set to on means that we should list all the files in that directory - * if non of the prev condition is true then we should return an error - */ - if (_is_dir()) // if the uri is a dir, then we should check if we have a autoindex=on so we should list all the files and return, else we should join it whith the root + std::vector allowed = _loc.getAllowedMethods(); + // lets first check for alowed methods in this location + if (find(allowed.begin(), allowed.end(), "GET") == allowed.end()) + { + _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); + return; + } + if (_is_dir()) { if (_loc.getAutoIndex() == "on") return; _root += '/' + _uri; _uri.clear(); } + /* + * if the location is the @default location then we should check the type of the uri, is it a directory or a file + * and if it's a direcotry then we should check if it containes one of the names in the index directive, then we should return + * it's content, otherwise we should check if the autoindex it set to on means that we should list all the files in that directory + * if non of the prev condition is true then we should return an error + */ if (_loc.getPath() == "/") { if (!_default_location()) // if we had an error while trying to open the file location we should return back From 35086c101202b389dc58f1d0347c00167df69c74 Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Sun, 21 Nov 2021 17:16:48 +0100 Subject: [PATCH 11/24] separete the locations to file and dir --- includes/response.hpp | 5 +-- main.cpp | 4 +-- src/hello.html | 0 src/response.cpp | 77 +++++++++++++++++++++++-------------------- 4 files changed, 47 insertions(+), 39 deletions(-) mode change 100644 => 100755 src/hello.html diff --git a/includes/response.hpp b/includes/response.hpp index ec3fdb4..d072ab4 100644 --- a/includes/response.hpp +++ b/includes/response.hpp @@ -22,11 +22,12 @@ class Response void Get_request(void); std::string const& get_response(void) const; private: - bool _default_location(void); void _set_headers(size_t, std::string const&, size_t, std::string const&); void _fill_response(std::string const&, size_t, std::string const&); bool _file_is_good(bool); - bool _is_dir(void) const; + bool _is_dir(std::string const&) const; + void _process_as_dir(void); + void _process_as_file(void); private: std::string _response; std::ifstream _file; diff --git a/main.cpp b/main.cpp index c564718..42dbc59 100644 --- a/main.cpp +++ b/main.cpp @@ -10,9 +10,9 @@ int main() std::vector allowed; index.push_back("hello.html"); index.push_back("index.html"); - allowed.push_back("POST"); + allowed.push_back("GET"); Location loc("/", index, allowed); - Response res("/Users/mamoussa/Desktop/42/webserv", loc, "src", "/Users/mamoussa/Desktop/42/webserv/error_pages"); + Response res("/Users/mamoussa/Desktop/42/webserv", loc, "", "/Users/mamoussa/Desktop/42/webserv/error_pages"); res.Get_request(); std::cout << res.get_response(); return EXIT_SUCCESS; diff --git a/src/hello.html b/src/hello.html old mode 100644 new mode 100755 diff --git a/src/response.cpp b/src/response.cpp index 3ca5bb9..b198c62 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -24,45 +24,29 @@ Response& Response::operator=(Response const& x) void Response::Get_request(void) { std::vector allowed = _loc.getAllowedMethods(); - // lets first check for alowed methods in this location + + //lets first check for alowed methods in this location if (find(allowed.begin(), allowed.end(), "GET") == allowed.end()) { _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); return; } - if (_is_dir()) - { - if (_loc.getAutoIndex() == "on") - return; - _root += '/' + _uri; - _uri.clear(); - } - /* - * if the location is the @default location then we should check the type of the uri, is it a directory or a file - * and if it's a direcotry then we should check if it containes one of the names in the index directive, then we should return - * it's content, otherwise we should check if the autoindex it set to on means that we should list all the files in that directory - * if non of the prev condition is true then we should return an error - */ + // first we have to check if the location is a dir or just a file if (_loc.getPath() == "/") - { - if (!_default_location()) // if we had an error while trying to open the file location we should return back - return; - } - if (_file_path.empty()) // if we get an empty path than we didn't found the file we are searching for in the index directive or we are not in the default location - { - if (!_file_is_good(true)) - return; - } - _fill_response(_file_path, 200, "OK"); // if all good than we should fill the response with 200 status code + _process_as_dir(); + else if (_is_dir(_root + '/' + _loc.getPath())) + _process_as_dir(); + else + _process_as_file(); } -bool Response::_default_location(void) +void Response::_process_as_dir(void) { std::vector const index = _loc.getIndex(); bool found(false); - - // first lets search if the location contains the uri as one of its index names - if (_uri.empty()) + + _root += '/' + _uri; + if (_uri.empty() || _is_dir(_root)) { for (size_t i = 0; i < index.size(); ++i) { @@ -70,25 +54,48 @@ bool Response::_default_location(void) if (!(found = _file_is_good(false)) && errno != 2) // if the file exists but we don't have the permissions to read from it { _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); - return false; + return; } else if (found) + { + if (!_file_is_good(true)) + return; + _fill_response(_file_path, 200, "OK"); break; + } } - if (!found) + if (!found && _loc.getAutoIndex() != "on") { _fill_response(_error_pages + '/' + "404.html", 404, "Not found"); - return false; - } + return; + } } - return true; + else + { + _file_path = _root; + if (!_file_is_good(true)) + return; + _fill_response(_file_path, 200, "OK"); + return; + } + // if we are here than we didn't found the file we are seaching on, and we have a intoindex set to on, so we should fill the template for + // autoindex on to list all the files in the dir +} + +void Response::_process_as_file(void) +{ + _file_path = _root + '/' + _uri; + if (!_file_is_good(true)) + return; + _fill_response(_file_path, 200, "OK"); + return; } -bool Response::_is_dir(void) const +bool Response::_is_dir(std::string const& path) const { struct stat s; - if (!lstat(_uri.c_str(), &s)) + if (!lstat(path.c_str(), &s)) { if (S_ISDIR(s.st_mode)) return true; From cba410a6152348aa5cf81450aa7e66ac6bdd9e1e Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Sun, 21 Nov 2021 20:36:29 +0100 Subject: [PATCH 12/24] added .php extention in GET --- includes/location.hpp | 1 + index.php | 1 + main.cpp | 2 +- src/response.cpp | 21 ++++++++++++++++----- 4 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 index.php diff --git a/includes/location.hpp b/includes/location.hpp index 60f5eca..a839bd1 100644 --- a/includes/location.hpp +++ b/includes/location.hpp @@ -17,4 +17,5 @@ class Location std::vector _index; std::vector _allowed_methods; std::string _autoIndex; + std::string _cgi_path; }; \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..ecad347 --- /dev/null +++ b/index.php @@ -0,0 +1 @@ +Hello World

'; ?> \ No newline at end of file diff --git a/main.cpp b/main.cpp index 42dbc59..90386fd 100644 --- a/main.cpp +++ b/main.cpp @@ -12,7 +12,7 @@ int main() index.push_back("index.html"); allowed.push_back("GET"); Location loc("/", index, allowed); - Response res("/Users/mamoussa/Desktop/42/webserv", loc, "", "/Users/mamoussa/Desktop/42/webserv/error_pages"); + Response res("/Users/mamoussa/Desktop/42/webserv", loc, "index.php", "/Users/mamoussa/Desktop/42/webserv/error_pages"); res.Get_request(); std::cout << res.get_response(); return EXIT_SUCCESS; diff --git a/src/response.cpp b/src/response.cpp index b198c62..465b373 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -11,6 +11,7 @@ Response::Response(std::string const& root, Location const& loc { _type.insert(std::make_pair("json", "application")); _type.insert(std::make_pair("html", "text")); + _type.insert(std::make_pair("php", "application/octet-stream")); } Response::Response(Response const& x) { *this = x; } @@ -23,16 +24,23 @@ Response& Response::operator=(Response const& x) void Response::Get_request(void) { - std::vector allowed = _loc.getAllowedMethods(); + std::vector allowed = _loc.getAllowedMethods(); + std::string const loc_path = _loc.getPath(); - //lets first check for alowed methods in this location + // lets first check for alowed methods in this location if (find(allowed.begin(), allowed.end(), "GET") == allowed.end()) { _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); return; } + // now lets check if we have to pass the file to the cgi (when we have a .php location), or process it as a static file otherwise + if (_uri.substr(_uri.find_last_of(".") + 1) == "php" && loc_path.substr(loc_path.find_first_of(".") + 1) == "php") + { + std::cout << "we have to call the cgi" << std::endl; + return; + } // first we have to check if the location is a dir or just a file - if (_loc.getPath() == "/") + if (loc_path == "/") _process_as_dir(); else if (_is_dir(_root + '/' + _loc.getPath())) _process_as_dir(); @@ -108,14 +116,17 @@ bool Response::_is_dir(std::string const& path) const void Response::_set_headers(size_t status_code, std::string const& message, size_t content_length, std::string const& path) { time_t rawtime; + std::string const extention = path.substr(path.find_last_of(".") + 1); time (&rawtime); _response += "HTTP/1.1 " + std::to_string(status_code) + " " + message + '\n'; _response += "Date: " + std::string(ctime(&rawtime)); _response += "Server: webserver\n"; _response += "Content-Length: " + std::to_string(content_length) + '\n'; - _response += "Content-Type: " + _type[path.substr(path.find_last_of(".") + 1)] + '/' - + path.substr(path.find_last_of(".") + 1) + '\n'; + if (extention == "php") + _response += "Content-Type: " + _type[extention] + '\n'; + else + _response += "Content-Type: " + _type[extention] + '/' + extention + '\n'; _response += "Connection: close\n"; _response += '\n'; } From c49017146903927b99816b4b5efa257e201a879e Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Wed, 24 Nov 2021 21:11:02 +0100 Subject: [PATCH 13/24] done testing POST req --- error_pages/405.html | 15 +++++++++++ includes/response.hpp | 2 ++ main.cpp | 14 +++++----- src/response.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++- test.c | 24 +++++++++++++++++ 5 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 error_pages/405.html create mode 100644 test.c diff --git a/error_pages/405.html b/error_pages/405.html new file mode 100644 index 0000000..7d04c1d --- /dev/null +++ b/error_pages/405.html @@ -0,0 +1,15 @@ + + + + 405 Not Allowed + + + +
+

405 Not Allowed

+
+
+
nginx/1.21.4
+ + + \ No newline at end of file diff --git a/includes/response.hpp b/includes/response.hpp index d072ab4..aeb4c81 100644 --- a/includes/response.hpp +++ b/includes/response.hpp @@ -3,6 +3,7 @@ # include # include # include +# include # include # include # include @@ -20,6 +21,7 @@ class Response ~Response(void); public: void Get_request(void); + void Post_request(void); std::string const& get_response(void) const; private: void _set_headers(size_t, std::string const&, size_t, std::string const&); diff --git a/main.cpp b/main.cpp index 90386fd..ecb8026 100644 --- a/main.cpp +++ b/main.cpp @@ -10,13 +10,11 @@ int main() std::vector allowed; index.push_back("hello.html"); index.push_back("index.html"); - allowed.push_back("GET"); - Location loc("/", index, allowed); - Response res("/Users/mamoussa/Desktop/42/webserv", loc, "index.php", "/Users/mamoussa/Desktop/42/webserv/error_pages"); - res.Get_request(); + allowed.push_back("POST"); + Location loc("/src", index, allowed); + Response res("/Users/mamoussa/Desktop/42/webserv", loc, "src", "/Users/mamoussa/Desktop/42/webserv/error_pages"); + // res.Get_request(); + res.Post_request(); std::cout << res.get_response(); return EXIT_SUCCESS; -} - - - +} \ No newline at end of file diff --git a/src/response.cpp b/src/response.cpp index 465b373..a5eb2da 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -22,6 +22,64 @@ Response& Response::operator=(Response const& x) return *this; } +void Response::Post_request(void) +{ + std::vector const allowed = _loc.getAllowedMethods(); + std::vector const index = _loc.getIndex(); + std::string const loc_path = _loc.getPath(); + bool found(false); + + // lets first check for alowed methods in this location + if (find(allowed.begin(), allowed.end(), "POST") == allowed.end()) + { + _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); + return; + } + // now lets check if we have to pass the file to the cgi (when we have a .php location), or process it as a static file otherwise + if (_uri.substr(_uri.find_last_of(".") + 1) == "php" && loc_path.substr(loc_path.find_last_of(".") + 1) == "php") + { + std::cout << "we have to call the cgi" << std::endl; + return; + } + // now if we have an other file extension than php, then we should return a error + if (!_is_dir(_root + '/' + _uri)) + { + if (!_file_is_good(true)) // if the file doesn't exist then we should return a not found message + return; + _fill_response(_error_pages + '/' + "405.html", 405, "Not Allowed"); + return; + } + else // if the _uri is a dir, then it behavios as get request, if the file not found we should return a 403 error + { + _root += '/' + _uri; + for (size_t i = 0; i < index.size(); ++i) + { + _file_path = _root + '/' + index[i]; + if (!(found = _file_is_good(false)) && errno != 2) // if the file exists but we don't have the permissions to read from it + { + _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); + return; + } + else if (found) + { + if (loc_path == "/") + { + _fill_response(_error_pages + '/' + "405.html", 405, "Not Allowed"); + return; + } + _fill_response(_file_path, 200, "OK"); + break; + } + } + if (!found && _loc.getAutoIndex() != "on") + { + _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); + return; + } + } + // if we are here then we have a dir in the _uri, and the auto index is set to on, so we should list all the files in the dir +} + void Response::Get_request(void) { std::vector allowed = _loc.getAllowedMethods(); @@ -34,7 +92,7 @@ void Response::Get_request(void) return; } // now lets check if we have to pass the file to the cgi (when we have a .php location), or process it as a static file otherwise - if (_uri.substr(_uri.find_last_of(".") + 1) == "php" && loc_path.substr(loc_path.find_first_of(".") + 1) == "php") + if (_uri.substr(_uri.find_last_of(".") + 1) == "php" && loc_path.substr(loc_path.find_last_of(".") + 1) == "php") { std::cout << "we have to call the cgi" << std::endl; return; diff --git a/test.c b/test.c new file mode 100644 index 0000000..2e15abc --- /dev/null +++ b/test.c @@ -0,0 +1,24 @@ +float Q_rsqrt( float number ) +{ + long i; + float x2, y; + const float threehalfs = 1.5F; + + x2 = number * 0.5F; + y = number; + i = * ( long * ) &y; // evil floating point bit level hacking + i = 0x5f3759df - ( i >> 1 ); // what the fuck? + y = * ( float * ) &i; + y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration +// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed + + return y; +} + +#include +int main(void) +{ + void *p = 0x5f3759df; + printf("%f\n", Q_rsqrt(1.3)); + return 0; +} From 6a881a34f13e728d2de3641a83e75eecac4f58a5 Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Thu, 25 Nov 2021 12:39:57 +0100 Subject: [PATCH 14/24] added DELETE method --- includes/response.hpp | 2 ++ main.cpp | 9 +++--- src/response.cpp | 69 ++++++++++++++++++++++++------------------- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/includes/response.hpp b/includes/response.hpp index aeb4c81..2457aae 100644 --- a/includes/response.hpp +++ b/includes/response.hpp @@ -22,6 +22,7 @@ class Response public: void Get_request(void); void Post_request(void); + void Delete_request(void); std::string const& get_response(void) const; private: void _set_headers(size_t, std::string const&, size_t, std::string const&); @@ -30,6 +31,7 @@ class Response bool _is_dir(std::string const&) const; void _process_as_dir(void); void _process_as_file(void); + void _process_post_delete(std::string const&); private: std::string _response; std::ifstream _file; diff --git a/main.cpp b/main.cpp index ecb8026..4e13d1c 100644 --- a/main.cpp +++ b/main.cpp @@ -10,11 +10,12 @@ int main() std::vector allowed; index.push_back("hello.html"); index.push_back("index.html"); - allowed.push_back("POST"); - Location loc("/src", index, allowed); - Response res("/Users/mamoussa/Desktop/42/webserv", loc, "src", "/Users/mamoussa/Desktop/42/webserv/error_pages"); + allowed.push_back("DELETE"); + Location loc(".php", index, allowed); + Response res("/Users/mamoussa/Desktop/42/webserv", loc, "index.php", "/Users/mamoussa/Desktop/42/webserv/error_pages"); // res.Get_request(); - res.Post_request(); + // res.Post_request(); + res.Delete_request(); std::cout << res.get_response(); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/src/response.cpp b/src/response.cpp index a5eb2da..8538acc 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -22,7 +22,37 @@ Response& Response::operator=(Response const& x) return *this; } -void Response::Post_request(void) +void Response::Delete_request(void) { _process_post_delete("DELETE"); } + +void Response::Post_request(void) { _process_post_delete("POST"); } + +void Response::Get_request(void) +{ + std::vector allowed = _loc.getAllowedMethods(); + std::string const loc_path = _loc.getPath(); + + // lets first check for alowed methods in this location + if (find(allowed.begin(), allowed.end(), "GET") == allowed.end()) + { + _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); + return; + } + // now lets check if we have to pass the file to the cgi (when we have a .php location), or process it as a static file otherwise + if (_uri.substr(_uri.find_last_of(".") + 1) == "php" && loc_path.substr(loc_path.find_last_of(".") + 1) == "php") + { + std::cout << "we have to call the cgi" << std::endl; + return; + } + // first we have to check if the location is a dir or just a file + if (loc_path == "/") + _process_as_dir(); + else if (_is_dir(_root + '/' + _loc.getPath())) + _process_as_dir(); + else + _process_as_file(); +} + +void Response::_process_post_delete(std::string const& req_method) { std::vector const allowed = _loc.getAllowedMethods(); std::vector const index = _loc.getIndex(); @@ -30,7 +60,7 @@ void Response::Post_request(void) bool found(false); // lets first check for alowed methods in this location - if (find(allowed.begin(), allowed.end(), "POST") == allowed.end()) + if (find(allowed.begin(), allowed.end(), req_method) == allowed.end()) { _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); return; @@ -41,7 +71,13 @@ void Response::Post_request(void) std::cout << "we have to call the cgi" << std::endl; return; } - // now if we have an other file extension than php, then we should return a error + // otherwise if the request method is delete then we should return a Not Allowed message + if (req_method == "DELETE") + { + _fill_response(_error_pages + '/' + "405.html", 405, "Not Allowed"); + return; + } + // now if we have an other file extension than php, then we should return an error if (!_is_dir(_root + '/' + _uri)) { if (!_file_is_good(true)) // if the file doesn't exist then we should return a not found message @@ -79,33 +115,6 @@ void Response::Post_request(void) } // if we are here then we have a dir in the _uri, and the auto index is set to on, so we should list all the files in the dir } - -void Response::Get_request(void) -{ - std::vector allowed = _loc.getAllowedMethods(); - std::string const loc_path = _loc.getPath(); - - // lets first check for alowed methods in this location - if (find(allowed.begin(), allowed.end(), "GET") == allowed.end()) - { - _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); - return; - } - // now lets check if we have to pass the file to the cgi (when we have a .php location), or process it as a static file otherwise - if (_uri.substr(_uri.find_last_of(".") + 1) == "php" && loc_path.substr(loc_path.find_last_of(".") + 1) == "php") - { - std::cout << "we have to call the cgi" << std::endl; - return; - } - // first we have to check if the location is a dir or just a file - if (loc_path == "/") - _process_as_dir(); - else if (_is_dir(_root + '/' + _loc.getPath())) - _process_as_dir(); - else - _process_as_file(); -} - void Response::_process_as_dir(void) { std::vector const index = _loc.getIndex(); From 440adb7a6bcb832a92e39198e26e1f0a21985b82 Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Thu, 25 Nov 2021 15:12:07 +0100 Subject: [PATCH 15/24] adding cgi meta-var --- includes/response.hpp | 3 ++ src/response.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++ test.c | 20 +------------ 3 files changed, 72 insertions(+), 19 deletions(-) diff --git a/includes/response.hpp b/includes/response.hpp index 2457aae..ec7b4dd 100644 --- a/includes/response.hpp +++ b/includes/response.hpp @@ -32,6 +32,8 @@ class Response void _process_as_dir(void); void _process_as_file(void); void _process_post_delete(std::string const&); + void _cgi(void); + void _set_cgi_meta_var(void); private: std::string _response; std::ifstream _file; @@ -40,5 +42,6 @@ class Response std::string _root; std::string _uri; std::string _error_pages; + std::string _cgi_meta_var; std::map _type; }; \ No newline at end of file diff --git a/src/response.cpp b/src/response.cpp index 8538acc..b2b6420 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -52,6 +52,74 @@ void Response::Get_request(void) _process_as_file(); } +void Response::_set_cgi_meta_var(void) +{ + /* + * SRC = Request (we will get this info from the request headers) + * The server MUST set this meta-variable if and only if the request is accompanied by a message body entity. + * The CONTENT_LENGTH value must reflect the length of the message-body + */ + _cgi_meta_var += "CONTENT_LENGHT=" + '\n'; + /* + * SRC = Request (we will get this info from the request headers) + * The server MUST set this meta-variable if an HTTP Content-Type field is present in the client request header. + */ + _cgi_meta_var += "CONTENT_TYPE=" + '\n'; + /* + * SRC = Static (hard code it) + * It MUST be set to the dialect of CGI being used by the server to communicate with the script. Example: CGI/1.1 + */ + _cgi_meta_var += "GATEWAY_INTERFACE=CGI/1.1\n"; + /* + * SRC = Request (we will get this info from the request headers) + * Extra "path" information. It's possible to pass extra info to your script in the URL, + * after the filename of the CGI script. For example, calling the + * URL http://www.myhost.com/mypath/myscript.cgi/path/info/here will set PATH_INFO to "/path/info/here". + * Commonly used for path-like data, but you can use it for anything. + */ + _cgi_meta_var += "PATH_INFO=" + '\n'; + /* + * SRC = Request/Conf (we will get this info from the request headers but we should parse it as a local uri) + * he PATH_TRANSLATED variable is derived by taking the PATH_INFO value, parsing it as a local URI in its own right, + * and performing any virtual-to-physical translation appropriate to map it onto the server's document repository structure + */ + _cgi_meta_var += "PATH_TRANSLATED=" + '\n'; + /* + * SRC = Request + * When information is sent using a method of GET, this variable contains the information in a query that follows the "?". + * The string is coded in the standard URL format of changing spaces to "+" and encoding special characters with "%xx" hexadecimal encoding. + * The CGI program must decode this information. + */ + _cgi_meta_var += "QUERY_STRING=" + '\n'; + /* + * SRC = Request + * Contains the method (as specified with the METHOD attribute in an HTML form) that is + * used to send the request. Example: GET + */ + _cgi_meta_var += "REQUEST_METHOD=" + '\n'; + /* + * SRC = Request + * The path part of the URL that points to the script being executed. + * It should include the leading slash. Example: /cgi-bin/hello.pgm + */ + _cgi_meta_var += "SCRIPT_NAME=" + '\n'; + /* + * SRC = Conf + * Contains the server host name or IP address of the server. Example: 10.9.8.7 + */ + _cgi_meta_var += "SERVER_NAME=" + '\n'; + /* + * Contains the port number to which the client request was sent. + */ + _cgi_meta_var += "SERVER_PORT=" + '\n'; + _cgi_meta_var += "SERVER_PROTOCOL=HTTP/1.1\n"; + _cgi_meta_var += "SERVER_SOFTWARE=Webserv\n"; +} +void Response::_cgi(void) +{ + // lets first set the cgi meta-variables +} + void Response::_process_post_delete(std::string const& req_method) { std::vector const allowed = _loc.getAllowedMethods(); diff --git a/test.c b/test.c index 2e15abc..64c5e83 100644 --- a/test.c +++ b/test.c @@ -1,24 +1,6 @@ -float Q_rsqrt( float number ) -{ - long i; - float x2, y; - const float threehalfs = 1.5F; - - x2 = number * 0.5F; - y = number; - i = * ( long * ) &y; // evil floating point bit level hacking - i = 0x5f3759df - ( i >> 1 ); // what the fuck? - y = * ( float * ) &i; - y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration -// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed - - return y; -} - #include +#include int main(void) { - void *p = 0x5f3759df; - printf("%f\n", Q_rsqrt(1.3)); return 0; } From 7c71d716b6a934cc1186320f2cbc81f615271994 Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Thu, 2 Dec 2021 13:11:11 +0100 Subject: [PATCH 16/24] added cgi redirection --- fork.cpp | 129 +++++++++++++++++++++++++++++++++++ includes/response.hpp | 6 +- index.php | 5 +- main.cpp | 6 +- src/{ => files}/hello.html | 0 src/response.cpp | 135 ++++++++++++++++++++++++++++++++----- 6 files changed, 256 insertions(+), 25 deletions(-) create mode 100644 fork.cpp rename src/{ => files}/hello.html (100%) diff --git a/fork.cpp b/fork.cpp new file mode 100644 index 0000000..a762f3c --- /dev/null +++ b/fork.cpp @@ -0,0 +1,129 @@ +#include +#include +#include +#include +#include +#include +#include + + +std::vector cgi_meta_var(void) +{ + std::vector meta_var; + std::string str; + /* + * SRC = Request (we will get this info from the request headers) + * The server MUST set this meta-variable if and only if the request is accompanied by a message body entity. + * The CONTENT_LENGTH value must reflect the length of the message-body + */ + str = std::string("CONTENT_LENGHT") + '\n'; + meta_var.push_back(str.c_str()); + // _cgi_meta_var += "CONTENT_LENGHT=" + '\n'; + /* + * SRC = Request (we will get this info from the request headers) + * The server MUST set this meta-variable if an HTTP Content-Type field is present in the client request header. + */ + str = std::string("CONTENT_TYPE=") + '\n'; + meta_var.push_back(str.c_str()); + /* + * SRC = Static (hard code it) + * It MUST be set to the dialect of CGI being used by the server to communicate with the script. Example: CGI/1.1 + */ + str = "GATEWAY_INTERFACE=CGI/1.1\n"; + meta_var.push_back(str.c_str()); + /* + * SRC = Request (we will get this info from the request headers) + * Extra "path" information. It's possible to pass extra info to your script in the URL, + * after the filename of the CGI script. For example, calling the + * URL http://www.myhost.com/mypath/myscript.cgi/path/info/here will set PATH_INFO to "/path/info/here". + * Commonly used for path-like data, but you can use it for anything. + */ + str = std::string("PATH_INFO=") + '\n'; + meta_var.push_back(str.c_str()); + /* + * SRC = Request/Conf (we will get this info from the request headers but we should parse it as a local uri) + * the PATH_TRANSLATED variable is derived by taking the PATH_INFO value, parsing it as a local URI in its own right, + * and performing any virtual-to-physical translation appropriate to map it onto the server's document repository structure + */ + str = std::string("PATH_TRANSLATED=") + '\n'; + meta_var.push_back(str.c_str()); + /* + * SRC = Request + * When information is sent using a method of GET, this variable contains the information in a query that follows the "?". + * The string is coded in the standard URL format of changing spaces to "+" and encoding special characters with "%xx" hexadecimal encoding. + * The CGI program must decode this information. + */ + str = std::string("QUERY_STRING=") + '\n'; + meta_var.push_back(str.c_str()); + /* + * SRC = Request + * Contains the method (as specified with the METHOD attribute in an HTML form) that is + * used to send the request. Example: GET + */ + str = std::string("REQUEST_METHOD=GET") + '\n'; + meta_var.push_back(str.c_str()); + /* + * SRC = Request + * The path part of the URL that points to the script being executed. + * It should include the leading slash. Example: /cgi-bin/hello.pgm + */ + str = std::string("SCRIPT_NAME=") + '\n'; + meta_var.push_back(str.c_str()); + /* + * SRC = Conf + * Contains the server host name or IP address of the server. Example: 10.9.8.7 + */ + str = std::string("SERVER_NAME=") + '\n'; + meta_var.push_back(str.c_str()); + /* + * Contains the port number to which the client request was sent. + */ + str = std::string("SERVER_PORT=") + '\n'; + meta_var.push_back(str.c_str()); + str = "SERVER_PROTOCOL=HTTP/1.1\n"; + meta_var.push_back(str.c_str()); + str = "SERVER_SOFTWARE=Webserv\n"; + meta_var.push_back(str.c_str()); + meta_var.push_back(NULL); + return meta_var; +} + +int main(void) +{ + int fd = open("index.php", O_RDONLY); + pid_t pid; + int pfd[2]; + + pipe(pfd); + if(!(pid = fork())) + { + std::vector meta_var = cgi_meta_var(); + std::vector args; + std::string path; + + args.push_back("/Users/mamoussa/Desktop/brew/bin/php-cgi"); + args.push_back(NULL); + path = "/Users/mamoussa/Desktop/brew/bin/php-cgi"; + close(pfd[0]); + dup2(fd, 0); + dup2(pfd[1], 1); + if (execve(path.c_str(), const_cast(&(*args.begin())) + , const_cast(&(*meta_var.begin()))) < 0) + { + meta_var.~vector(); + args.~vector(); + std::cout << strerror(errno) << std::endl; + exit(1); + } + } + wait(&pid); + close(pfd[1]); + std::string ans; + char buff[1024]; + int ret = 1; + + while ((ret = read(pfd[0], buff, 1024))) + ans += buff; + std::cout << ans << std::endl; + return 0; +} \ No newline at end of file diff --git a/includes/response.hpp b/includes/response.hpp index ec7b4dd..09e1b9d 100644 --- a/includes/response.hpp +++ b/includes/response.hpp @@ -26,14 +26,15 @@ class Response std::string const& get_response(void) const; private: void _set_headers(size_t, std::string const&, size_t, std::string const&); + bool _check_for_red(std::string const&); void _fill_response(std::string const&, size_t, std::string const&); bool _file_is_good(bool); bool _is_dir(std::string const&) const; void _process_as_dir(void); void _process_as_file(void); void _process_post_delete(std::string const&); - void _cgi(void); - void _set_cgi_meta_var(void); + void _cgi(std::string const&); + void _fill_cgi_response(std::string const&); private: std::string _response; std::ifstream _file; @@ -42,6 +43,5 @@ class Response std::string _root; std::string _uri; std::string _error_pages; - std::string _cgi_meta_var; std::map _type; }; \ No newline at end of file diff --git a/index.php b/index.php index ecad347..dc92b87 100644 --- a/index.php +++ b/index.php @@ -1 +1,4 @@ -Hello World

'; ?> \ No newline at end of file +Hello World

'; +header("Pragma: no-cache"); +// header('Location: /index.html'); +?> \ No newline at end of file diff --git a/main.cpp b/main.cpp index 4e13d1c..e4b0786 100644 --- a/main.cpp +++ b/main.cpp @@ -10,12 +10,12 @@ int main() std::vector allowed; index.push_back("hello.html"); index.push_back("index.html"); - allowed.push_back("DELETE"); + allowed.push_back("GET"); Location loc(".php", index, allowed); Response res("/Users/mamoussa/Desktop/42/webserv", loc, "index.php", "/Users/mamoussa/Desktop/42/webserv/error_pages"); - // res.Get_request(); + res.Get_request(); // res.Post_request(); - res.Delete_request(); +// res.Delete_request(); std::cout << res.get_response(); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/src/hello.html b/src/files/hello.html similarity index 100% rename from src/hello.html rename to src/files/hello.html diff --git a/src/response.cpp b/src/response.cpp index b2b6420..682dd69 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -40,7 +40,7 @@ void Response::Get_request(void) // now lets check if we have to pass the file to the cgi (when we have a .php location), or process it as a static file otherwise if (_uri.substr(_uri.find_last_of(".") + 1) == "php" && loc_path.substr(loc_path.find_last_of(".") + 1) == "php") { - std::cout << "we have to call the cgi" << std::endl; + _cgi("GET"); return; } // first we have to check if the location is a dir or just a file @@ -52,24 +52,30 @@ void Response::Get_request(void) _process_as_file(); } -void Response::_set_cgi_meta_var(void) +std::vector cgi_meta_var(void) { + std::vector meta_var; + std::string str; /* * SRC = Request (we will get this info from the request headers) * The server MUST set this meta-variable if and only if the request is accompanied by a message body entity. * The CONTENT_LENGTH value must reflect the length of the message-body */ - _cgi_meta_var += "CONTENT_LENGHT=" + '\n'; + str = std::string("CONTENT_LENGHT") + '\n'; + meta_var.push_back(str.c_str()); + // _cgi_meta_var += "CONTENT_LENGHT=" + '\n'; /* * SRC = Request (we will get this info from the request headers) * The server MUST set this meta-variable if an HTTP Content-Type field is present in the client request header. */ - _cgi_meta_var += "CONTENT_TYPE=" + '\n'; + str = std::string("CONTENT_TYPE=") + '\n'; + meta_var.push_back(str.c_str()); /* * SRC = Static (hard code it) * It MUST be set to the dialect of CGI being used by the server to communicate with the script. Example: CGI/1.1 */ - _cgi_meta_var += "GATEWAY_INTERFACE=CGI/1.1\n"; + str = "GATEWAY_INTERFACE=CGI/1.1\n"; + meta_var.push_back(str.c_str()); /* * SRC = Request (we will get this info from the request headers) * Extra "path" information. It's possible to pass extra info to your script in the URL, @@ -77,47 +83,139 @@ void Response::_set_cgi_meta_var(void) * URL http://www.myhost.com/mypath/myscript.cgi/path/info/here will set PATH_INFO to "/path/info/here". * Commonly used for path-like data, but you can use it for anything. */ - _cgi_meta_var += "PATH_INFO=" + '\n'; + str = std::string("PATH_INFO=") + '\n'; + meta_var.push_back(str.c_str()); /* * SRC = Request/Conf (we will get this info from the request headers but we should parse it as a local uri) - * he PATH_TRANSLATED variable is derived by taking the PATH_INFO value, parsing it as a local URI in its own right, + * the PATH_TRANSLATED variable is derived by taking the PATH_INFO value, parsing it as a local URI in its own right, * and performing any virtual-to-physical translation appropriate to map it onto the server's document repository structure */ - _cgi_meta_var += "PATH_TRANSLATED=" + '\n'; + str = std::string("PATH_TRANSLATED=") + '\n'; + meta_var.push_back(str.c_str()); /* * SRC = Request * When information is sent using a method of GET, this variable contains the information in a query that follows the "?". * The string is coded in the standard URL format of changing spaces to "+" and encoding special characters with "%xx" hexadecimal encoding. * The CGI program must decode this information. */ - _cgi_meta_var += "QUERY_STRING=" + '\n'; + str = std::string("QUERY_STRING=") + '\n'; + meta_var.push_back(str.c_str()); /* * SRC = Request * Contains the method (as specified with the METHOD attribute in an HTML form) that is * used to send the request. Example: GET */ - _cgi_meta_var += "REQUEST_METHOD=" + '\n'; + str = std::string("REQUEST_METHOD=") + '\n'; + meta_var.push_back(str.c_str()); /* * SRC = Request * The path part of the URL that points to the script being executed. * It should include the leading slash. Example: /cgi-bin/hello.pgm */ - _cgi_meta_var += "SCRIPT_NAME=" + '\n'; + str = std::string("SCRIPT_NAME=") + '\n'; + meta_var.push_back(str.c_str()); /* * SRC = Conf * Contains the server host name or IP address of the server. Example: 10.9.8.7 */ - _cgi_meta_var += "SERVER_NAME=" + '\n'; + str = std::string("SERVER_NAME=") + '\n'; + meta_var.push_back(str.c_str()); /* * Contains the port number to which the client request was sent. */ - _cgi_meta_var += "SERVER_PORT=" + '\n'; - _cgi_meta_var += "SERVER_PROTOCOL=HTTP/1.1\n"; - _cgi_meta_var += "SERVER_SOFTWARE=Webserv\n"; + str = std::string("SERVER_PORT=") + '\n'; + meta_var.push_back(str.c_str()); + str = "SERVER_PROTOCOL=HTTP/1.1\n"; + meta_var.push_back(str.c_str()); + str = "SERVER_SOFTWARE=Webserv\n"; + meta_var.push_back(str.c_str()); + meta_var.push_back(NULL); + return meta_var; } -void Response::_cgi(void) + +std::string get_res(int fd) +{ + std::string ans; + char buff[1024]; + int ret; + + while ((ret = read(fd, buff, 1024))) + ans += buff; + return ans; +} + +bool Response::_check_for_red(std::string const& tmp_res) +{ + std::string substr; + std::string const string_to_search("Location"); + size_t index; + + // lets check if we have a Location header field means that we have a redirection + if ((index = tmp_res.find(string_to_search)) != std::string::npos) + { + // we will take a substring from the index where we found the Location header field + the length of the Location string + size_t start_search = index + string_to_search.length() + 1; + substr = tmp_res.substr(start_search, tmp_res.find_first_of('\n', start_search) - start_search); + // now we should trim all the spaces and tabes we have in the substr + while (*substr.begin() == ' ' || *substr.begin() == '\t' || *substr.begin() == '/') + substr.erase(substr.begin()); + substr.erase(substr.end() - 1); + // then we override the uri atter to be the new location + _uri = substr; + return true; + } + return false; +} + +void Response::_fill_cgi_response(std::string const& tmp_res) { - // lets first set the cgi meta-variables + +} + +void Response::_cgi(std::string const& req_method) +{ + int fd = open("index.php", O_RDONLY); + pid_t pid; + int pfd[2]; + std::string tmp_res; + + pipe(pfd); + if(!(pid = fork())) + { + std::vector meta_var = cgi_meta_var(); + std::vector args; + std::string path; + + args.push_back("/Users/mamoussa/Desktop/brew/bin/php-cgi"); + args.push_back(NULL); + path = "/Users/mamoussa/Desktop/brew/bin/php-cgi"; + close(pfd[0]); + dup2(fd, 0); + dup2(pfd[1], 1); + if (execve(path.c_str(), const_cast(&(*args.begin())) + , const_cast(&(*meta_var.begin()))) < 0) + { + meta_var.~vector(); + args.~vector(); + std::cout << strerror(errno) << std::endl; + exit(1); + } + exit(1); + } + wait(&pid); + close(pfd[1]); + tmp_res = get_res(pfd[0]); + if (_check_for_red(tmp_res)) + { + if (req_method == "GET") + this->Get_request(); + else if (req_method == "POST") + this->Post_request(); + else + this->Delete_request(); + } + else + _fill_cgi_response(tmp_res); } void Response::_process_post_delete(std::string const& req_method) @@ -136,7 +234,7 @@ void Response::_process_post_delete(std::string const& req_method) // now lets check if we have to pass the file to the cgi (when we have a .php location), or process it as a static file otherwise if (_uri.substr(_uri.find_last_of(".") + 1) == "php" && loc_path.substr(loc_path.find_last_of(".") + 1) == "php") { - std::cout << "we have to call the cgi" << std::endl; + _cgi(req_method); return; } // otherwise if the request method is delete then we should return a Not Allowed message @@ -183,6 +281,7 @@ void Response::_process_post_delete(std::string const& req_method) } // if we are here then we have a dir in the _uri, and the auto index is set to on, so we should list all the files in the dir } + void Response::_process_as_dir(void) { std::vector const index = _loc.getIndex(); From 0865dfd70d400c65fd57c17eec32278d4f24341c Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Thu, 2 Dec 2021 17:28:16 +0100 Subject: [PATCH 17/24] added bade gataway in cgi --- error_pages/502.html | 15 +++++++ includes/response.hpp | 5 +-- index.php | 2 +- main.cpp | 3 +- src/response.cpp | 95 ++++++++++++++++++++----------------------- 5 files changed, 65 insertions(+), 55 deletions(-) create mode 100644 error_pages/502.html diff --git a/error_pages/502.html b/error_pages/502.html new file mode 100644 index 0000000..3b829f9 --- /dev/null +++ b/error_pages/502.html @@ -0,0 +1,15 @@ + + + + 502 Bad Gateway + + + +
+

502 Bad Gateway

+
+
+
nginx/1.21.4
+ + + \ No newline at end of file diff --git a/includes/response.hpp b/includes/response.hpp index 09e1b9d..6dbaf4c 100644 --- a/includes/response.hpp +++ b/includes/response.hpp @@ -26,15 +26,14 @@ class Response std::string const& get_response(void) const; private: void _set_headers(size_t, std::string const&, size_t, std::string const&); - bool _check_for_red(std::string const&); void _fill_response(std::string const&, size_t, std::string const&); bool _file_is_good(bool); bool _is_dir(std::string const&) const; void _process_as_dir(void); void _process_as_file(void); void _process_post_delete(std::string const&); - void _cgi(std::string const&); - void _fill_cgi_response(std::string const&); + void _cgi(void); + void _fill_cgi_response(std::string const&, bool); private: std::string _response; std::ifstream _file; diff --git a/index.php b/index.php index dc92b87..6b2fedf 100644 --- a/index.php +++ b/index.php @@ -1,4 +1,4 @@ Hello World

'; header("Pragma: no-cache"); -// header('Location: /index.html'); +// header('Location: https://datatracker.ietf.org/doc/html/rfc3875#section-4.2'); ?> \ No newline at end of file diff --git a/main.cpp b/main.cpp index e4b0786..5b2e152 100644 --- a/main.cpp +++ b/main.cpp @@ -3,6 +3,7 @@ #include #include #include +#include int main() { @@ -17,5 +18,5 @@ int main() // res.Post_request(); // res.Delete_request(); std::cout << res.get_response(); - return EXIT_SUCCESS; + return 0; } \ No newline at end of file diff --git a/src/response.cpp b/src/response.cpp index 682dd69..601b205 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -40,7 +40,7 @@ void Response::Get_request(void) // now lets check if we have to pass the file to the cgi (when we have a .php location), or process it as a static file otherwise if (_uri.substr(_uri.find_last_of(".") + 1) == "php" && loc_path.substr(loc_path.find_last_of(".") + 1) == "php") { - _cgi("GET"); + _cgi(); return; } // first we have to check if the location is a dir or just a file @@ -144,43 +144,32 @@ std::string get_res(int fd) return ans; } -bool Response::_check_for_red(std::string const& tmp_res) -{ - std::string substr; - std::string const string_to_search("Location"); - size_t index; - - // lets check if we have a Location header field means that we have a redirection - if ((index = tmp_res.find(string_to_search)) != std::string::npos) - { - // we will take a substring from the index where we found the Location header field + the length of the Location string - size_t start_search = index + string_to_search.length() + 1; - substr = tmp_res.substr(start_search, tmp_res.find_first_of('\n', start_search) - start_search); - // now we should trim all the spaces and tabes we have in the substr - while (*substr.begin() == ' ' || *substr.begin() == '\t' || *substr.begin() == '/') - substr.erase(substr.begin()); - substr.erase(substr.end() - 1); - // then we override the uri atter to be the new location - _uri = substr; - return true; - } - return false; -} - -void Response::_fill_cgi_response(std::string const& tmp_res) +void Response::_fill_cgi_response(std::string const& tmp_res, bool is_red) { + time_t rawtime; + time (&rawtime); + if(is_red) + _response += "HTTP/1.1 302 Found\r\n"; + else + _response += "HTTP/1.1 200 OK\r\n"; + _response += "Date: " + std::string(ctime(&rawtime)) + "\r\n"; + _response += "Server: webserver\r\n"; + _response += "Transfer-Encoding: chunked\r\n"; + _response += "Connection: close\r\n"; + _response += tmp_res; } -void Response::_cgi(std::string const& req_method) +void Response::_cgi(void) { int fd = open("index.php", O_RDONLY); - pid_t pid; - int pfd[2]; + int pfd[2]; std::string tmp_res; + size_t index; + int status; pipe(pfd); - if(!(pid = fork())) + if(!(fork())) { std::vector meta_var = cgi_meta_var(); std::vector args; @@ -195,27 +184,33 @@ void Response::_cgi(std::string const& req_method) if (execve(path.c_str(), const_cast(&(*args.begin())) , const_cast(&(*meta_var.begin()))) < 0) { + close(pfd[1]); meta_var.~vector(); args.~vector(); - std::cout << strerror(errno) << std::endl; exit(1); } - exit(1); + exit(0); } - wait(&pid); + wait(&status); close(pfd[1]); - tmp_res = get_res(pfd[0]); - if (_check_for_red(tmp_res)) + // first lets check if the cgi path is correct + if (WEXITSTATUS(status) == 1) { - if (req_method == "GET") - this->Get_request(); - else if (req_method == "POST") - this->Post_request(); - else - this->Delete_request(); + close(pfd[0]); + close(fd); + _fill_response(_error_pages + '/' + "502.html", 502, "Bad Gateway"); + return; } + tmp_res = get_res(pfd[0]); + // if the tmp_res contains the Status header field then we should erase it, because it will be added + if ((index = tmp_res.find("Status")) != std::string::npos) + tmp_res.erase(tmp_res.begin() + index, tmp_res.begin() + tmp_res.find_first_of('\n', index) + 1); + if (tmp_res.find("Location") != std::string::npos) + _fill_cgi_response(tmp_res, true); else - _fill_cgi_response(tmp_res); + _fill_cgi_response(tmp_res, false); + close(pfd[0]); + close(fd); } void Response::_process_post_delete(std::string const& req_method) @@ -234,7 +229,7 @@ void Response::_process_post_delete(std::string const& req_method) // now lets check if we have to pass the file to the cgi (when we have a .php location), or process it as a static file otherwise if (_uri.substr(_uri.find_last_of(".") + 1) == "php" && loc_path.substr(loc_path.find_last_of(".") + 1) == "php") { - _cgi(req_method); + _cgi(); return; } // otherwise if the request method is delete then we should return a Not Allowed message @@ -353,16 +348,16 @@ void Response::_set_headers(size_t status_code, std::string const& message, size std::string const extention = path.substr(path.find_last_of(".") + 1); time (&rawtime); - _response += "HTTP/1.1 " + std::to_string(status_code) + " " + message + '\n'; - _response += "Date: " + std::string(ctime(&rawtime)); - _response += "Server: webserver\n"; - _response += "Content-Length: " + std::to_string(content_length) + '\n'; + _response += "HTTP/1.1 " + std::to_string(status_code) + " " + message + "\r\n"; + _response += "Date: " + std::string(ctime(&rawtime)) + "\r\n"; + _response += "Server: webserver\r\n"; + _response += "Content-Length: " + std::to_string(content_length) + "\r\n"; if (extention == "php") - _response += "Content-Type: " + _type[extention] + '\n'; + _response += "Content-Type: " + _type[extention] + "\r\n"; else - _response += "Content-Type: " + _type[extention] + '/' + extention + '\n'; - _response += "Connection: close\n"; - _response += '\n'; + _response += "Content-Type: " + _type[extention] + '/' + extention + "\r\n"; + _response += "Connection: close\r\n"; + _response += "\r\n"; } void Response::_fill_response(std::string const& path, size_t status_code, std::string const& message) From 3869674e52e535c9d8c876ed6f345ed2aaa8961a Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Fri, 3 Dec 2021 15:41:08 +0100 Subject: [PATCH 18/24] added local error page --- includes/response.hpp | 2 ++ index.php | 2 +- main.cpp | 4 +-- src/response.cpp | 83 ++++++++++++++++++++++++++++--------------- 4 files changed, 59 insertions(+), 32 deletions(-) diff --git a/includes/response.hpp b/includes/response.hpp index 6dbaf4c..d24c273 100644 --- a/includes/response.hpp +++ b/includes/response.hpp @@ -5,8 +5,10 @@ # include # include # include +# include # include # include +# include # include # include # include "location.hpp" diff --git a/index.php b/index.php index 6b2fedf..82752ad 100644 --- a/index.php +++ b/index.php @@ -1,4 +1,4 @@ Hello World

'; header("Pragma: no-cache"); -// header('Location: https://datatracker.ietf.org/doc/html/rfc3875#section-4.2'); +header("Location: https://datatracker.ietf.org/doc/html/rfc3875#section-4.2"); ?> \ No newline at end of file diff --git a/main.cpp b/main.cpp index 5b2e152..4d4862b 100644 --- a/main.cpp +++ b/main.cpp @@ -12,8 +12,8 @@ int main() index.push_back("hello.html"); index.push_back("index.html"); allowed.push_back("GET"); - Location loc(".php", index, allowed); - Response res("/Users/mamoussa/Desktop/42/webserv", loc, "index.php", "/Users/mamoussa/Desktop/42/webserv/error_pages"); + Location loc("/", index, allowed); + Response res("/Users/mamoussa/Desktop/42/webserv", loc, "file.json", "/Users/mamoussa/Desktop/42/webserv/error_pages"); res.Get_request(); // res.Post_request(); // res.Delete_request(); diff --git a/src/response.cpp b/src/response.cpp index 601b205..e0e1455 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -26,6 +26,17 @@ void Response::Delete_request(void) { _process_post_delete("DELETE"); } void Response::Post_request(void) { _process_post_delete("POST"); } +std::string *error_page(std::string const& message) +{ + std::string *error_body = new std::string(); + + *error_body += std::string("\r\n\r\n"); + *error_body += std::string("") + message; + *error_body += std::string("\r\n\r\n\r\n
\r\n

") + message; + *error_body += std::string("

\r\n
\r\n
\r\n
webserver
\r\n\r\n\r\n"); + return error_body; +} + void Response::Get_request(void) { std::vector allowed = _loc.getAllowedMethods(); @@ -34,7 +45,7 @@ void Response::Get_request(void) // lets first check for alowed methods in this location if (find(allowed.begin(), allowed.end(), "GET") == allowed.end()) { - _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); + _fill_response(".html", 403, "Forbiden"); return; } // now lets check if we have to pass the file to the cgi (when we have a .php location), or process it as a static file otherwise @@ -153,7 +164,7 @@ void Response::_fill_cgi_response(std::string const& tmp_res, bool is_red) _response += "HTTP/1.1 302 Found\r\n"; else _response += "HTTP/1.1 200 OK\r\n"; - _response += "Date: " + std::string(ctime(&rawtime)) + "\r\n"; + _response += "Date: " + std::string(ctime(&rawtime)); _response += "Server: webserver\r\n"; _response += "Transfer-Encoding: chunked\r\n"; _response += "Connection: close\r\n"; @@ -198,8 +209,8 @@ void Response::_cgi(void) { close(pfd[0]); close(fd); - _fill_response(_error_pages + '/' + "502.html", 502, "Bad Gateway"); - return; + _fill_response(".html", 502, "Bad Gateway"); + return; } tmp_res = get_res(pfd[0]); // if the tmp_res contains the Status header field then we should erase it, because it will be added @@ -223,7 +234,7 @@ void Response::_process_post_delete(std::string const& req_method) // lets first check for alowed methods in this location if (find(allowed.begin(), allowed.end(), req_method) == allowed.end()) { - _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); + _fill_response(".html", 403, "Forbiden"); return; } // now lets check if we have to pass the file to the cgi (when we have a .php location), or process it as a static file otherwise @@ -235,7 +246,7 @@ void Response::_process_post_delete(std::string const& req_method) // otherwise if the request method is delete then we should return a Not Allowed message if (req_method == "DELETE") { - _fill_response(_error_pages + '/' + "405.html", 405, "Not Allowed"); + _fill_response(".html", 405, "Not Allowed"); return; } // now if we have an other file extension than php, then we should return an error @@ -243,7 +254,7 @@ void Response::_process_post_delete(std::string const& req_method) { if (!_file_is_good(true)) // if the file doesn't exist then we should return a not found message return; - _fill_response(_error_pages + '/' + "405.html", 405, "Not Allowed"); + _fill_response(".html", 405, "Not Allowed"); return; } else // if the _uri is a dir, then it behavios as get request, if the file not found we should return a 403 error @@ -254,14 +265,14 @@ void Response::_process_post_delete(std::string const& req_method) _file_path = _root + '/' + index[i]; if (!(found = _file_is_good(false)) && errno != 2) // if the file exists but we don't have the permissions to read from it { - _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); + _fill_response(".html", 403, "Forbiden"); return; } else if (found) { if (loc_path == "/") { - _fill_response(_error_pages + '/' + "405.html", 405, "Not Allowed"); + _fill_response(".html", 405, "Not Allowed"); return; } _fill_response(_file_path, 200, "OK"); @@ -270,7 +281,7 @@ void Response::_process_post_delete(std::string const& req_method) } if (!found && _loc.getAutoIndex() != "on") { - _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); + _fill_response(".html", 403, "Forbiden"); return; } } @@ -290,7 +301,7 @@ void Response::_process_as_dir(void) _file_path = _root + '/' + index[i]; if (!(found = _file_is_good(false)) && errno != 2) // if the file exists but we don't have the permissions to read from it { - _fill_response(_error_pages + '/' + "403.html", 403, "Forbiden"); + _fill_response(".html", 403, "Forbiden"); return; } else if (found) @@ -303,7 +314,7 @@ void Response::_process_as_dir(void) } if (!found && _loc.getAutoIndex() != "on") { - _fill_response(_error_pages + '/' + "404.html", 404, "Not found"); + _fill_response(".html", 404, "Not found"); return; } } @@ -346,12 +357,17 @@ void Response::_set_headers(size_t status_code, std::string const& message, size { time_t rawtime; std::string const extention = path.substr(path.find_last_of(".") + 1); + std::stringstream ss, ss_content; + ss << status_code; time (&rawtime); - _response += "HTTP/1.1 " + std::to_string(status_code) + " " + message + "\r\n"; - _response += "Date: " + std::string(ctime(&rawtime)) + "\r\n"; + _response += "HTTP/1.1 " + ss.str() + " " + message + "\r\n"; + _response += "Date: " + std::string(ctime(&rawtime)); + _response.erase(--_response.end()); + _response += "\r\n"; _response += "Server: webserver\r\n"; - _response += "Content-Length: " + std::to_string(content_length) + "\r\n"; + ss_content << content_length; + _response += "Content-Length: " + ss_content.str() + "\r\n"; if (extention == "php") _response += "Content-Type: " + _type[extention] + "\r\n"; else @@ -363,24 +379,33 @@ void Response::_set_headers(size_t status_code, std::string const& message, size void Response::_fill_response(std::string const& path, size_t status_code, std::string const& message) { std::string line; - std::string tmp_resp; - size_t content_counter(0); + std::string *tmp_resp = new std::string(); - _file.open(path); - while (!_file.eof()) + if (status_code == 200) { - std::getline(_file, line); - content_counter += line.size(); - if (!_file.eof()) + _file.open(path); + while (!_file.eof()) { - line += '\n'; - content_counter++; + std::getline(_file, line); + if (!_file.eof()) + line += "\r\n"; + *tmp_resp += line; } - tmp_resp += line; + *tmp_resp += "\r\n"; + } + else + { + std::stringstream ss; + std::string buff; + ss << status_code; + ss >> buff; + delete tmp_resp; + tmp_resp = error_page(buff + ' ' + message); } // set all the needed response header - _set_headers(status_code, message, content_counter, path); - _response += tmp_resp; + _set_headers(status_code, message, tmp_resp->length(), path); + _response += *tmp_resp; + delete tmp_resp; } bool Response::_file_is_good(bool fill_resp) @@ -390,9 +415,9 @@ bool Response::_file_is_good(bool fill_resp) if (open(_file_path.c_str(), O_RDONLY) < 0) { if (errno == 2 && fill_resp) - _fill_response(_error_pages + '/' + "404.html", 404, "Not Found"); + _fill_response(".html", 404, "Not Found"); else if (fill_resp) - _fill_response(_error_pages + '/' + "403.html", 403, "Forbidden"); + _fill_response(".html", 403, "Forbidden"); return false; } return true; From 8de8d09023ffea3323c95fcfdcf30aa04a534abb Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Fri, 3 Dec 2021 20:03:51 +0100 Subject: [PATCH 19/24] added autoindex --- includes/location.hpp | 2 +- includes/response.hpp | 3 +++ main.cpp | 26 +++++++++++++++++--- src/response.cpp | 56 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 81 insertions(+), 6 deletions(-) diff --git a/includes/location.hpp b/includes/location.hpp index a839bd1..5fc473c 100644 --- a/includes/location.hpp +++ b/includes/location.hpp @@ -11,7 +11,7 @@ class Location std::string const& getPath(void) const { return _path; } std::vector getIndex(void) const { return _index; } std::vector getAllowedMethods(void) const { return _allowed_methods; } - std::string const& getAutoIndex(void) const { return _autoIndex;} + std::string & getAutoIndex(void) { return _autoIndex;} private: std::string _path; std::vector _index; diff --git a/includes/response.hpp b/includes/response.hpp index d24c273..9b9002f 100644 --- a/includes/response.hpp +++ b/includes/response.hpp @@ -11,6 +11,7 @@ # include # include # include +# include # include "location.hpp" class Response @@ -36,6 +37,8 @@ class Response void _process_post_delete(std::string const&); void _cgi(void); void _fill_cgi_response(std::string const&, bool); + void _auto_index_list(void); + void _fill_auto_index_response(std::string *); private: std::string _response; std::ifstream _file; diff --git a/main.cpp b/main.cpp index 4d4862b..6232931 100644 --- a/main.cpp +++ b/main.cpp @@ -3,7 +3,8 @@ #include #include #include -#include +#include +#include int main() { @@ -13,10 +14,29 @@ int main() index.push_back("index.html"); allowed.push_back("GET"); Location loc("/", index, allowed); - Response res("/Users/mamoussa/Desktop/42/webserv", loc, "file.json", "/Users/mamoussa/Desktop/42/webserv/error_pages"); + loc.getAutoIndex() = "on"; + Response res("/Users/mamoussa/Desktop/42/webserv", loc, "src", "/Users/mamoussa/Desktop/42/webserv/error_pages"); res.Get_request(); - // res.Post_request(); +// res.Post_request(); // res.Delete_request(); std::cout << res.get_response(); + // struct dirent *cur_dir; + + // DIR* dir = opendir("/Users/mamoussa/Desktop/42/webserv/src"); + // if (!dir) + // { + // std::cout << "permission denied" << std::endl; + // return 0; + // } + // while ((cur_dir = readdir(dir))) + // { + // std::cout << "d_ino \t" << cur_dir->d_ino << std::endl; + // std::cout << "d_name \t" << cur_dir->d_name << std::endl; + // std::cout << "d_namlen \t" << cur_dir->d_namlen << std::endl; + // std::cout << "d_reclen \t" << cur_dir->d_reclen << std::endl; + // std::cout << "d_seekoff \t" << cur_dir->d_seekoff << std::endl; + // std::cout << "d_type \t" << cur_dir->d_type << std::endl; + // std::cout << "---------------------------------------" << std::endl; + // } return 0; } \ No newline at end of file diff --git a/src/response.cpp b/src/response.cpp index e0e1455..87c55e1 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -224,6 +224,57 @@ void Response::_cgi(void) close(fd); } +void Response::_fill_auto_index_response(std::string* tmp_res) +{ + time_t rawtime; + + time (&rawtime); + _response += "HTTP/1.1 200 OK\r\n"; + _response += "Date: " + std::string(ctime(&rawtime)); + _response.erase(--_response.end()); + _response += "\r\n"; + _response += "Server: webserver\r\n"; + _response += "Transfer-Encoding: chunked\r\n"; + _response += "Connection: close\r\n"; + _response += "\r\n"; + _response += *tmp_res; +} + +void Response::_auto_index_list(void) +{ + std::string *tmp_res = new std::string(); + DIR* dir; + struct dirent *dir_info; + + dir = opendir(_root.c_str()); + if (!dir) + { + _fill_response(".html", 403, "Forbidden"); + return; + } + *tmp_res += std::string("\r\n\r\nIndex of " + _uri + "\r\n"); + *tmp_res += "\r\n\r\n"; + *tmp_res += std::string("

Index of " + _uri + "

\r\n"); + *tmp_res += "
\r\n
\r\n";
+	while ((dir_info = readdir(dir)))
+	{
+		if (std::string(dir_info->d_name) == ".")
+			continue;
+		if (std::string(dir_info->d_name) == "..")
+		{
+			*tmp_res += "..\r\n");
+			continue;
+		}
+		*tmp_res += std::string("d_name) + "\">" + std::string(dir_info->d_name) + "\r\n";
+	}
+	*tmp_res += "
\r\n
\r\n\r\n\r\n"; + _fill_auto_index_response(tmp_res); + delete tmp_res; + closedir(dir); +} + void Response::_process_post_delete(std::string const& req_method) { std::vector const allowed = _loc.getAllowedMethods(); @@ -328,6 +379,7 @@ void Response::_process_as_dir(void) } // if we are here than we didn't found the file we are seaching on, and we have a intoindex set to on, so we should fill the template for // autoindex on to list all the files in the dir + _auto_index_list(); } void Response::_process_as_file(void) @@ -395,8 +447,8 @@ void Response::_fill_response(std::string const& path, size_t status_code, std:: } else { - std::stringstream ss; - std::string buff; + std::stringstream ss; + std::string buff; ss << status_code; ss >> buff; delete tmp_resp; From 3d1d06f4d92bd26c1d55d718e4a50674c73fed39 Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Fri, 3 Dec 2021 22:44:07 +0100 Subject: [PATCH 20/24] done implementing the autoindex --- Makefile | 2 +- includes/response.hpp | 2 +- main.cpp | 4 ++-- src/response.cpp | 22 ++++++++++++---------- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 6facba4..5195c87 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ SRC = main.cpp src/response.cpp CMP = clang++ -std=c++98 -FLAGS = -Wall -Wextra -Werror -fsanitize=address -g3 +FLAGS = -Wall -Wextra -Werror -g3 NAME = a.out all : $(NAME) diff --git a/includes/response.hpp b/includes/response.hpp index 9b9002f..f14a781 100644 --- a/includes/response.hpp +++ b/includes/response.hpp @@ -36,7 +36,7 @@ class Response void _process_as_file(void); void _process_post_delete(std::string const&); void _cgi(void); - void _fill_cgi_response(std::string const&, bool); + void _fill_cgi_response(std::string *, bool); void _auto_index_list(void); void _fill_auto_index_response(std::string *); private: diff --git a/main.cpp b/main.cpp index 6232931..75e675d 100644 --- a/main.cpp +++ b/main.cpp @@ -5,7 +5,6 @@ #include #include #include - int main() { std::vector index; @@ -13,13 +12,14 @@ int main() index.push_back("hello.html"); index.push_back("index.html"); allowed.push_back("GET"); - Location loc("/", index, allowed); + Location loc("/src", index, allowed); loc.getAutoIndex() = "on"; Response res("/Users/mamoussa/Desktop/42/webserv", loc, "src", "/Users/mamoussa/Desktop/42/webserv/error_pages"); res.Get_request(); // res.Post_request(); // res.Delete_request(); std::cout << res.get_response(); + // system("leaks a.out"); // struct dirent *cur_dir; // DIR* dir = opendir("/Users/mamoussa/Desktop/42/webserv/src"); diff --git a/src/response.cpp b/src/response.cpp index 87c55e1..c5f18a4 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -144,18 +144,18 @@ std::vector cgi_meta_var(void) return meta_var; } -std::string get_res(int fd) +std::string *get_res(int fd) { - std::string ans; + std::string *ans = new std::string(); char buff[1024]; int ret; while ((ret = read(fd, buff, 1024))) - ans += buff; + *ans += buff; return ans; } -void Response::_fill_cgi_response(std::string const& tmp_res, bool is_red) +void Response::_fill_cgi_response(std::string *tmp_res, bool is_red) { time_t rawtime; @@ -168,14 +168,14 @@ void Response::_fill_cgi_response(std::string const& tmp_res, bool is_red) _response += "Server: webserver\r\n"; _response += "Transfer-Encoding: chunked\r\n"; _response += "Connection: close\r\n"; - _response += tmp_res; + _response += *tmp_res; } void Response::_cgi(void) { int fd = open("index.php", O_RDONLY); int pfd[2]; - std::string tmp_res; + std::string *tmp_res; size_t index; int status; @@ -196,8 +196,8 @@ void Response::_cgi(void) , const_cast(&(*meta_var.begin()))) < 0) { close(pfd[1]); - meta_var.~vector(); args.~vector(); + // delete meta_var; exit(1); } exit(0); @@ -214,14 +214,15 @@ void Response::_cgi(void) } tmp_res = get_res(pfd[0]); // if the tmp_res contains the Status header field then we should erase it, because it will be added - if ((index = tmp_res.find("Status")) != std::string::npos) - tmp_res.erase(tmp_res.begin() + index, tmp_res.begin() + tmp_res.find_first_of('\n', index) + 1); - if (tmp_res.find("Location") != std::string::npos) + if ((index = tmp_res->find("Status")) != std::string::npos) + tmp_res->erase(tmp_res->begin() + index, tmp_res->begin() + tmp_res->find_first_of('\n', index) + 1); + if (tmp_res->find("Location") != std::string::npos) _fill_cgi_response(tmp_res, true); else _fill_cgi_response(tmp_res, false); close(pfd[0]); close(fd); + delete tmp_res; } void Response::_fill_auto_index_response(std::string* tmp_res) @@ -337,6 +338,7 @@ void Response::_process_post_delete(std::string const& req_method) } } // if we are here then we have a dir in the _uri, and the auto index is set to on, so we should list all the files in the dir + _auto_index_list(); } void Response::_process_as_dir(void) From f809642a6ccd0b35b49d2f026337787f525369bc Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Fri, 3 Dec 2021 23:50:02 +0100 Subject: [PATCH 21/24] modif in the way i fill the response when i found the file return instead of break --- index.php | 2 +- main.cpp | 9 +++++---- src/file.html | 0 src/response.cpp | 35 +++++++++++++++++++---------------- 4 files changed, 25 insertions(+), 21 deletions(-) mode change 100644 => 100755 src/file.html diff --git a/index.php b/index.php index 82752ad..f391a4d 100644 --- a/index.php +++ b/index.php @@ -1,4 +1,4 @@ Hello World

'; header("Pragma: no-cache"); -header("Location: https://datatracker.ietf.org/doc/html/rfc3875#section-4.2"); +// header("Location: https://datatracker.ietf.org/doc/html/rfc3875#section-4.2"); ?> \ No newline at end of file diff --git a/main.cpp b/main.cpp index 75e675d..e14cc49 100644 --- a/main.cpp +++ b/main.cpp @@ -10,13 +10,14 @@ int main() std::vector index; std::vector allowed; index.push_back("hello.html"); + index.push_back("file.html"); index.push_back("index.html"); - allowed.push_back("GET"); + allowed.push_back("POST"); Location loc("/src", index, allowed); - loc.getAutoIndex() = "on"; + loc.getAutoIndex() = "off"; Response res("/Users/mamoussa/Desktop/42/webserv", loc, "src", "/Users/mamoussa/Desktop/42/webserv/error_pages"); - res.Get_request(); -// res.Post_request(); + // res.Get_request(); + res.Post_request(); // res.Delete_request(); std::cout << res.get_response(); // system("leaks a.out"); diff --git a/src/file.html b/src/file.html old mode 100644 new mode 100755 diff --git a/src/response.cpp b/src/response.cpp index c5f18a4..d9b5e84 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -1,7 +1,7 @@ #include "../includes/response.hpp" #include "../includes/location.hpp" - +/* this is the implementation of the default, param, and copy constructors plus the operator=*/ Response::Response(void): _response(""), _loc() , _root(""), _uri(""), _error_pages(""){} @@ -21,22 +21,13 @@ Response& Response::operator=(Response const& x) _response = x._response; return *this; } +/*-------------------------------------------------------------------------------*/ +/* those are the public methods to process the request @GET @POST @DELETE */ void Response::Delete_request(void) { _process_post_delete("DELETE"); } void Response::Post_request(void) { _process_post_delete("POST"); } -std::string *error_page(std::string const& message) -{ - std::string *error_body = new std::string(); - - *error_body += std::string("\r\n\r\n"); - *error_body += std::string("") + message; - *error_body += std::string("\r\n\r\n\r\n
\r\n

") + message; - *error_body += std::string("

\r\n
\r\n
\r\n
webserver
\r\n\r\n\r\n"); - return error_body; -} - void Response::Get_request(void) { std::vector allowed = _loc.getAllowedMethods(); @@ -62,7 +53,8 @@ void Response::Get_request(void) else _process_as_file(); } - +/*----------------------------------------------------------------------------*/ +/* this part is for the cgi (fill the meta_var and excute it) */ std::vector cgi_meta_var(void) { std::vector meta_var; @@ -224,7 +216,8 @@ void Response::_cgi(void) close(fd); delete tmp_res; } - +/*---------------------------------------------------------------------------------------------------*/ +/* this part is for the files and subdirectoreis listing e.i when we have the auto indexing */ void Response::_fill_auto_index_response(std::string* tmp_res) { time_t rawtime; @@ -275,7 +268,17 @@ void Response::_auto_index_list(void) delete tmp_res; closedir(dir); } +/*-----------------------------------------------------------------------------------------------------*/ +std::string *error_page(std::string const& message) +{ + std::string *error_body = new std::string(); + *error_body += std::string("\r\n\r\n"); + *error_body += std::string("") + message; + *error_body += std::string("\r\n\r\n\r\n
\r\n

") + message; + *error_body += std::string("

\r\n
\r\n
\r\n
webserver
\r\n\r\n\r\n"); + return error_body; +} void Response::_process_post_delete(std::string const& req_method) { std::vector const allowed = _loc.getAllowedMethods(); @@ -328,7 +331,7 @@ void Response::_process_post_delete(std::string const& req_method) return; } _fill_response(_file_path, 200, "OK"); - break; + return; } } if (!found && _loc.getAutoIndex() != "on") @@ -362,7 +365,7 @@ void Response::_process_as_dir(void) if (!_file_is_good(true)) return; _fill_response(_file_path, 200, "OK"); - break; + return; } } if (!found && _loc.getAutoIndex() != "on") From fb1107ca8b19617ff4a83dbae0a1ab0662afc2b2 Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Sat, 4 Dec 2021 20:26:35 +0100 Subject: [PATCH 22/24] last push before merge --- src/file.html => file.html | 0 hello.html | 0 main.cpp | 4 ++-- src/files/hello.html | 6 ------ src/response.cpp | 2 +- user_login.php | 16 ++++++++++++++++ 6 files changed, 19 insertions(+), 9 deletions(-) rename src/file.html => file.html (100%) mode change 100644 => 100755 hello.html delete mode 100755 src/files/hello.html create mode 100644 user_login.php diff --git a/src/file.html b/file.html similarity index 100% rename from src/file.html rename to file.html diff --git a/hello.html b/hello.html old mode 100644 new mode 100755 diff --git a/main.cpp b/main.cpp index e14cc49..9b8cf25 100644 --- a/main.cpp +++ b/main.cpp @@ -13,9 +13,9 @@ int main() index.push_back("file.html"); index.push_back("index.html"); allowed.push_back("POST"); - Location loc("/src", index, allowed); + Location loc(".php", index, allowed); loc.getAutoIndex() = "off"; - Response res("/Users/mamoussa/Desktop/42/webserv", loc, "src", "/Users/mamoussa/Desktop/42/webserv/error_pages"); + Response res("/Users/mamoussa/Desktop/42/webserv", loc, "user_login.php", "/Users/mamoussa/Desktop/42/webserv/error_pages"); // res.Get_request(); res.Post_request(); // res.Delete_request(); diff --git a/src/files/hello.html b/src/files/hello.html deleted file mode 100755 index bfd56b7..0000000 --- a/src/files/hello.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - hello - - \ No newline at end of file diff --git a/src/response.cpp b/src/response.cpp index d9b5e84..ad52cd7 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -165,7 +165,7 @@ void Response::_fill_cgi_response(std::string *tmp_res, bool is_red) void Response::_cgi(void) { - int fd = open("index.php", O_RDONLY); + int fd = open("user_login.php", O_RDONLY); int pfd[2]; std::string *tmp_res; size_t index; diff --git a/user_login.php b/user_login.php new file mode 100644 index 0000000..924a755 --- /dev/null +++ b/user_login.php @@ -0,0 +1,16 @@ + \ No newline at end of file From 87259c2e0b9fc03bb482142b6b40ea93a1d2a572 Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Sat, 4 Dec 2021 20:34:49 +0100 Subject: [PATCH 23/24] remove .vscode --- .vscode/launch.json | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 7b51bce..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "Debug", - "program": "${workspaceFolder}/a.out", - "args": [], - "cwd": "${workspaceFolder}" - } - ] -} \ No newline at end of file From c9a32e2fee25f7df34b97ed35587f2052754c109 Mon Sep 17 00:00:00 2001 From: Mohamed Amoussaoui Date: Sat, 4 Dec 2021 20:45:03 +0100 Subject: [PATCH 24/24] remove some stuff --- a.out.dSYM/Contents/Info.plist | 20 -------------------- test.c | 6 ------ test.cpp | 0 3 files changed, 26 deletions(-) delete mode 100644 a.out.dSYM/Contents/Info.plist delete mode 100644 test.c delete mode 100644 test.cpp diff --git a/a.out.dSYM/Contents/Info.plist b/a.out.dSYM/Contents/Info.plist deleted file mode 100644 index 3679a65..0000000 --- a/a.out.dSYM/Contents/Info.plist +++ /dev/null @@ -1,20 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleIdentifier - com.apple.xcode.dsym.a.out - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - dSYM - CFBundleSignature - ???? - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/test.c b/test.c deleted file mode 100644 index 64c5e83..0000000 --- a/test.c +++ /dev/null @@ -1,6 +0,0 @@ -#include -#include -int main(void) -{ - return 0; -} diff --git a/test.cpp b/test.cpp deleted file mode 100644 index e69de29..0000000