From 9ee7205b95e6de1304e431c1a54af36a3905f696 Mon Sep 17 00:00:00 2001 From: Me Date: Mon, 8 Aug 2022 02:50:37 +0200 Subject: [PATCH] Index and Autoindex work nicely, standarized way paths for root and location path are stored in config, still needs a little polishing prolly --- default.config | 26 +--- srcs/config/LocationConfig.hpp | 39 +----- srcs/config/ServerConfig.hpp | 24 +--- srcs/config/parser.cpp | 33 +---- srcs/config/postProcessing.cpp | 6 +- srcs/utils.cpp | 15 --- srcs/webserv/Webserv.hpp | 1 + srcs/webserv/autoindex.hpp | 2 +- srcs/webserv/response.cpp | 118 +++++++++++------- www/test/index1.html | 2 +- www/test/something.html | 2 +- .../test_deeper/{index.html => index1.html} | 2 +- www/test/test_deeper/something.html | 2 +- 13 files changed, 99 insertions(+), 173 deletions(-) rename www/test/test_deeper/{index.html => index1.html} (70%) diff --git a/default.config b/default.config index ed483e0..7277066 100644 --- a/default.config +++ b/default.config @@ -10,30 +10,13 @@ server { # client_body_limit 400; index index.html; # this is another comment -# i think root requires leading / -# root goop; -# root ./www/; - root ./www; -# root www/test; # also works -# root /www; # stat does not like this kind of definition -# root /usr; # because it's looking at / aka absolute path -# root ~/Programming/42/group_webserv/www; # didn't like thise either -# root /home/me/Programming/42/group_webserv; # but this is fine + + root ./www/; location /test { -# root /www/test; - autoindex on; + index something.html; } -# If not explicitly set, ConfigParser need to genererate a location block -# like this for path "/" (based on field "root" and "index" of the server) -# location / { -# root /www; -# index index.html; -# allow_methods DELETE; -# } - -# location /test/something.html { location /test/something.html { allow_methods DELETE; } @@ -41,7 +24,8 @@ server { # location /something/long/here { # } - location /test/test_deeper { + location /test/test_deeper/ { + autoindex on; } location /test/test_deeper/something.html { diff --git a/srcs/config/LocationConfig.hpp b/srcs/config/LocationConfig.hpp index cc09353..72a4886 100644 --- a/srcs/config/LocationConfig.hpp +++ b/srcs/config/LocationConfig.hpp @@ -30,22 +30,16 @@ class LocationConfig public: // canonic stuff? - // i thought this might fix the "non static member function" - // shit i'm getting with the comparator... - LocationConfig() {} - ~LocationConfig() {} - - - std::string path; - - std::string root; + std::string path; // /path and /path/ are fine + // i add trailing / if a dir + std::string root; std::vector index; unsigned int allow_methods; std::vector cgi_ext; // php not .php - - bool autoindex; + bool autoindex; std::vector upload_repo; + // wait if i can call several times, shouldn't it be a map? // wait no there can only be 1 and i think it might have to be in // location only... @@ -79,12 +73,6 @@ public: int comp_rhs = 0; size_t tmp = 0; - // What are the rules... - // / is smaller than /test - // and /test/test1 is bigger than test - // so we want to count / - - while ((tmp = this->path.find_first_of("/", tmp)) != std::string::npos) { ++tmp; @@ -101,23 +89,6 @@ public: if (rhs.path[rhs.path.find_last_of("/") + 1] != '\0') ++comp_rhs; - // ok now we need to add a thing where we check for files vs folders -/* if (comp_lhs == comp_rhs) - { - if (path_is_valid(root + path) == 2) - --comp_lhs; - if (path_is_valid(rhs.root + rhs.path) == 2) - --comp_rhs; - } -*/ - -// std::cout << "comp_lhs: " << comp_lhs << " comp_rhs: " << comp_rhs -// << " bool res: " << (comp_lhs > comp_rhs) << "\n"; - // i honestly can't tell you how or why but using > rather than < - // fixed all my problems - // the fact that the bool was always 0 before, and the correct order - // i want... super weird... - // return (comp_lhs > comp_rhs); return (comp_lhs < comp_rhs); // right comparison ? not <= ? }; diff --git a/srcs/config/ServerConfig.hpp b/srcs/config/ServerConfig.hpp index ceee50a..c0feecf 100644 --- a/srcs/config/ServerConfig.hpp +++ b/srcs/config/ServerConfig.hpp @@ -14,44 +14,24 @@ class ServerConfig { public: - // do i need some canonic stuff? - - // there can be several std::vector server_name; // we could shove default in here if we wanted to... - // there can only be 1 per server... std::string host; std::string port; // port needs to be something else... not quite an int - // should a Server be able to handle several? - // there can only be one. - std::string root; + std::string root; // ./www/ or www work www/ and www work + // i do remove trailing / tho unsigned int client_body_limit; // set to default max if none set - // might be the only one we let slide if bad input... It remains false... - - // we will check the index in the post processing with access() ? std::vector index; std::map error_pages; - // fuck it, you can only call allow_methods once in Server - std::vector locations; - // not convinced we need these... -// struct timeval send_timeout; -// struct timeval recv_timeout; - - -// fuck maybe i do need return here... - // wait if i can call several times, shouldn't it be a map? -// i think actually there can only be 1 and it can only be in a location? -// int redirect_status; -// std::string redirect_uri; void print_all() { diff --git a/srcs/config/parser.cpp b/srcs/config/parser.cpp index 982b160..36a0ae2 100644 --- a/srcs/config/parser.cpp +++ b/srcs/config/parser.cpp @@ -148,8 +148,6 @@ LocationConfig ConfigParser::_parse_location(size_t *start) if (ret.path[0] != '/') ret.path.insert(0, "/"); // throw std::invalid_argument("Location path require a leading /"); - if (ret.path.back() != '/') - ret.path.push_back('/'); // in theory now curr should be right after the "path" curr = _content.find_first_not_of(" \t\n", curr); @@ -233,19 +231,10 @@ void ConfigParser::_set_server_values(ServerConfig *server, \ } else if (key == "root" && size == 1 && server->root == "") { -// if (tmp_val[0][0] != '/') -// throw std::invalid_argument("Root requires leading /"); - // remove trailing / - if (tmp_val[0].back() == '/') - tmp_val[0].erase(tmp_val[0].size(), 1); - - // std::cout << "root: " << tmp_val[0] << '\n'; -//might not even do these checks here... -// if (path_is_valid(tmp_val[0]) == 1) - server->root = tmp_val[0]; -// else -// throw std::invalid_argument("Root dir invalid 1"); + if (tmp_val[0][tmp_val[0].size() - 1] == '/') + tmp_val[0].erase(tmp_val[0].size() - 1, 1); + server->root = tmp_val[0]; } else if (key == "client_body_limit" && size == 1 \ && server->client_body_limit == 0) @@ -257,9 +246,6 @@ void ConfigParser::_set_server_values(ServerConfig *server, \ else if (key == "index") { // i think you can call index several times... - // should i be doing an access? - // since index is at the root, but root might not yet be defined - // will check index later in post for (unsigned long i = 0; i != tmp_val.size(); i++) server->index.push_back(tmp_val[i]); } @@ -288,11 +274,7 @@ void ConfigParser::_set_server_values(ServerConfig *server, \ } } else - { - // means either you didn't write the right key, or the value is - // missing, or the value has already been filled. throw std::invalid_argument("bad key value pair"); - } } @@ -313,8 +295,9 @@ void ConfigParser::_set_location_values(LocationConfig *location, \ // throw std::invalid_argument("Root requires leading /"); // remove trailing / - if (tmp_val[0].back() == '/') - tmp_val[0].erase(tmp_val[0].size(), 1); + // if (tmp_val[0].back() == '/') + if (tmp_val[0][tmp_val[0].size() - 1] == '/') + tmp_val[0].erase(tmp_val[0].size() - 1, 1); // if (path_is_valid(tmp_val[0]) == 1) location->root = tmp_val[0]; // else @@ -367,11 +350,7 @@ void ConfigParser::_set_location_values(LocationConfig *location, \ location->redirect_uri = tmp_val[1]; } else - { - // means either you didn't write the right key, or the value is - // missing, or the value has already been filled. throw std::invalid_argument("bad key value pair"); - } } diff --git a/srcs/config/postProcessing.cpp b/srcs/config/postProcessing.cpp index c35968f..61f338a 100644 --- a/srcs/config/postProcessing.cpp +++ b/srcs/config/postProcessing.cpp @@ -57,7 +57,7 @@ void ConfigParser::_post_processing(std::vector *servers) // same for redirect status i think - // maybe do something for Cgi_info? + // maybe do something for Cgi_ext? // std::cout << "In Post, Root + Path: " << it_l->root + it_l->path << '\n'; /* if (path_is_valid(it_l->root + it_l->path) == 0) @@ -66,6 +66,10 @@ void ConfigParser::_post_processing(std::vector *servers) throw std::invalid_argument("location path is invalid"); } */ + if (path_is_valid(it_l->root + it_l->path) == 1 \ + && it_l->path[it_l->path.size() - 1] != '/') + it_l->path.push_back('/'); + ++it_l; } diff --git a/srcs/utils.cpp b/srcs/utils.cpp index f8c498d..b53f4a7 100644 --- a/srcs/utils.cpp +++ b/srcs/utils.cpp @@ -93,8 +93,6 @@ std::string http_methods_to_str(unsigned int methods) // you could make this &path... int path_is_valid(std::string path) { -// std::string i_path = path.substr(1); -// const char *tmp_path = i_path.c_str(); const char *tmp_path = path.c_str(); struct stat s; @@ -111,19 +109,6 @@ int path_is_valid(std::string path) return (1); } } - -/* - if (stat(tmp_path, &s) == 0 && S_ISREG(s.st_mode)) // a File - { - std::cout << "is a file\n"; - return (2); - } - else if (stat(tmp_path, &s) == 0 && S_ISDIR(s.st_mode)) // A Folder - { - std::cout << "is a Dir\n"; - return (1); - } -*/ // std::cout << "path is neither dir nor file\n"; return (0); } diff --git a/srcs/webserv/Webserv.hpp b/srcs/webserv/Webserv.hpp index e5fe312..246a818 100644 --- a/srcs/webserv/Webserv.hpp +++ b/srcs/webserv/Webserv.hpp @@ -24,6 +24,7 @@ # include // string # include // perror, remove # include // atoi (athough it's already cover by ) +# include // opendir() # include "Client.hpp" # include "ServerConfig.hpp" diff --git a/srcs/webserv/autoindex.hpp b/srcs/webserv/autoindex.hpp index 88911e3..1fc9f9e 100644 --- a/srcs/webserv/autoindex.hpp +++ b/srcs/webserv/autoindex.hpp @@ -8,7 +8,7 @@ ""\ ""\ ""\ - " Index of " + "<title>Index of " # define AUTOINDEX_MID1 \ ""\ diff --git a/srcs/webserv/response.cpp b/srcs/webserv/response.cpp index 5a4b0eb..70d0aaa 100644 --- a/srcs/webserv/response.cpp +++ b/srcs/webserv/response.cpp @@ -134,32 +134,64 @@ void Webserv::_error_html_response(Client *client, ServerConfig &server) #define INDEX "index.html" // temp wip void Webserv::_get(Client *client, ServerConfig &server, LocationConfig &location) { - (void)server; // To remove from arg if we determine its useless - std::string path = client->get_path(); - - if (path == "/") // TODO : index and autoindex - path.append(INDEX); - path.insert(0, location.root); - - std::cerr << "path = " << path << "\n"; - - std::cout << "ERIC path: " << path << '\n'; - /* RULES ** if path is a valid dir check if index is specified and serve that if no index and autoindex, server that if file, server that! +WHere does cgi fit in in all this ??? + +THIS NEEDS WORK... + +*/ + (void)server; // To remove from arg if we determine its useless + std::string path = client->get_path(); + +/* if (path == "/") // TODO : index and autoindex + path.append(INDEX); + path.insert(0, location.root); */ + // that was actually a horrible idea... + path.insert(0, location.root); + std::cerr << "path = " << path << "\n"; -// std::cout << "location: " << location.path << " autoindex: " << location.autoindex << '\n'; - if (path_is_valid(path) == 1 && location.autoindex == true) + // path = root + location.path + // we will tack on an index if there is a valid one + // or autoindex if allowed + // or let _get_file sort out the error otherwise. + + if (path_is_valid(path) == 1) { - std::cout << "about to call autoindex\n"; - _autoindex(client, location, path); + std::cout << "path is valid\n"; + if (path[path.size() - 1] != '/') + path.push_back('/'); + for (size_t i = 0; i < location.index.size(); i++) + { + std::cout << "location path: " << location.path << '\n'; + std::cout << "location index: " << location.index[i] << '\n'; +// std::cout << "path with index: " << path + location.index[i] << '\n'; + if (path_is_valid(path + location.index[i]) == 2) + { + std::cout << "found a valid index\n"; + path.append(location.index[i]); + break ; // what if index and autoindex in a single location? + // does this completely fail? + // do this instead of break? + //_get_file(client, path); + } + } + if (location.autoindex == true) + { + _autoindex(client, location, path); + return ; + } } +// else +// _get_file(client, path); + // what about cgi ??? + // TMP HUGO @@ -175,29 +207,21 @@ if file, server that! _get_file(client, path); } -// i might need some sort of _generate_autoindex() - -#include -#include +// i only sort of need &path... +// def can improve but works for now... void Webserv::_autoindex(Client *client, LocationConfig &location, std::string &path) { - // i think the plan is to generate an html file and return it - // it should be filled with the stuff that is found in that repo - - // either i create a tmp file and put the html in it an call - // the _get_file on it with a new path... - // or i make the html and do what _get_file does if it found - // a valid file... - - // Let's try the 2nd one first. - std::cout << "made it to _autoindex\n"; - std::string dir_list; - DIR *dir; - struct dirent *ent; + std::string dir_list; + DIR *dir; + struct dirent *ent; + std::cout << "location root: " << location.root << " location path: " \ + << location.path << '\n'; + +// if ((dir = opendir (path.c_str())) != NULL) if ((dir = opendir ((location.root + location.path).c_str())) != NULL) { /* print all the files and directories within directory */ @@ -208,44 +232,36 @@ void Webserv::_autoindex(Client *client, LocationConfig &location, std::string & dir_list.append(AUTOINDEX_MID2); while ((ent = readdir (dir)) != NULL) { -// printf ("%s\n", ent->d_name); if (strcmp(".", ent->d_name) == 0) continue ; dir_list.append("d_name); dir_list.append("\">"); dir_list.append(ent->d_name); dir_list.append(""); - dir_list.append("\r\n"); + dir_list.append("\r\n"); // is this right? } // nginx.org.
+// index1.html + +// apparently this is more than good enough! +// .. dir_list.append(AUTOINDEX_END); - _append_body(client, dir_list.c_str(), dir_list.size(), "html"); - + std::cout << "\n\n" << dir_list << '\n'; closedir (dir); + _append_body(client, dir_list.c_str(), dir_list.size(), "html"); } else { + // in theory not possible cuz we already checked... /* could not open directory */ // perror (""); std::cout << "could not open dir\n"; return ; } - - - - - - - - // if successful we call _append_body - } @@ -255,6 +271,8 @@ void Webserv::_get_file(Client *client, const std::string &path) std::ifstream ifd; // For chunk, ifstream directly in struct CLient for multiples read without close() ? // char buf[MAX_FILESIZE+1]; + std::cout << "made it to get_file\n"; + if (access(path.c_str(), F_OK) == -1) { std::perror("err access()"); @@ -489,6 +507,10 @@ LocationConfig &Webserv::_determine_location(ServerConfig &server, std::string & // if (it->path.compare(0, path.size(), path) == 0) if (it->path.compare(0, it->path.size(), path) == 0) break; +// kinda gross i know but... have to deal with when there's a / at the end + if (it->path[it->path.size() - 1] == '/' \ + && it->path.compare(0, it->path.size() - 1, path) == 0) + break; ++it; } if (it != server.locations.end()) diff --git a/www/test/index1.html b/www/test/index1.html index ba02623..1db5ee9 100644 --- a/www/test/index1.html +++ b/www/test/index1.html @@ -4,7 +4,7 @@ Webserv test index -

Le index (˘ ͜ʖ˘)

+

Webserv Test Index


(˚3˚)

diff --git a/www/test/something.html b/www/test/something.html index 3e8a32f..5eb0f8b 100644 --- a/www/test/something.html +++ b/www/test/something.html @@ -4,7 +4,7 @@ Webserv test Something -

Le index (˘ ͜ʖ˘)

+

Webserv Test Something


(˚3˚)

diff --git a/www/test/test_deeper/index.html b/www/test/test_deeper/index1.html similarity index 70% rename from www/test/test_deeper/index.html rename to www/test/test_deeper/index1.html index 2992159..c5c0b87 100644 --- a/www/test/test_deeper/index.html +++ b/www/test/test_deeper/index1.html @@ -4,7 +4,7 @@ Webserv Test Deeper Index -

Le index (˘ ͜ʖ˘)

+

Webserv Test Deeper Index


(˚3˚)

diff --git a/www/test/test_deeper/something.html b/www/test/test_deeper/something.html index 44f17ac..c864180 100644 --- a/www/test/test_deeper/something.html +++ b/www/test/test_deeper/something.html @@ -4,7 +4,7 @@ Webserv test deeper Something -

Le index (˘ ͜ʖ˘)

+

Webserv Test Deeper Something


(˚3˚)