From 8e90221058f8cae42b00b7d2a9461b15de65ffcd Mon Sep 17 00:00:00 2001 From: Me Date: Wed, 10 Aug 2022 01:59:10 +0200 Subject: [PATCH] location picker works, needs to be tested more tho --- default.config | 13 ++++- srcs/config/LocationConfig.hpp | 6 +-- srcs/config/extraConfig.cpp | 17 +----- srcs/config/parser.cpp | 49 ++++++----------- srcs/config/postProcessing.cpp | 14 +---- srcs/webserv/response.cpp | 97 ++++++++++++++++++++++++++++++++-- www/error_pages/error_404.html | 11 ++++ www/test/index1.html | 2 +- 8 files changed, 141 insertions(+), 68 deletions(-) create mode 100644 www/error_pages/error_404.html diff --git a/default.config b/default.config index 17399b2..7972cad 100644 --- a/default.config +++ b/default.config @@ -13,8 +13,19 @@ server { root ./www/; + error_page 404 ./www/error_pages/error_404.html; + + location /test { - index index1.html; + index index1.html subdex.html; + } + + location /test/index1.html { + index index1.html subdex.html; + } + + location /hilarious_404/ { + redirect 301 https://berniesanders.com/404/; } # /stylesheet/ alone doesn't work, i mean we don't have wildcards... diff --git a/srcs/config/LocationConfig.hpp b/srcs/config/LocationConfig.hpp index 66de1c5..b6b5b3e 100644 --- a/srcs/config/LocationConfig.hpp +++ b/srcs/config/LocationConfig.hpp @@ -38,10 +38,10 @@ public: std::vector cgi_ext; // php not .php bool autoindex; - std::string upload_repo; // might change name... + std::string upload_dir; - int redirect_status; - std::string redirect_uri; + int redirect_status; // only in location + std::string redirect_uri; // only 1 per location // au pire you do location / { return 301 http://location; } // and that's how you get the redirect from the root. diff --git a/srcs/config/extraConfig.cpp b/srcs/config/extraConfig.cpp index dfd770b..747e2cd 100644 --- a/srcs/config/extraConfig.cpp +++ b/srcs/config/extraConfig.cpp @@ -19,8 +19,8 @@ std::string ConfigParser::_pre_set_val_check(const std::string key, \ // there shouldn't be any tabs, right? not between values... if (value.find_first_of("\t") != std::string::npos) { - std::cout << value << "\n"; - throw std::invalid_argument("bad config file arguments 3"); +// std::cout << value << "\n"; + throw std::invalid_argument("why would you put tabs between values"); } size_t i = value.find_first_of(";"); @@ -33,11 +33,6 @@ std::string ConfigParser::_pre_set_val_check(const std::string key, \ throw std::invalid_argument("bad config file arguments 4"); - // we Trim value. - // is this valid? - // would it be better to shove the result directly in tmp_val? - // like call substr in split? - //value = value.substr(0, i - 1); return (value.substr(0, i)); } @@ -68,17 +63,10 @@ std::string ConfigParser::_get_rest_of_line(size_t *curr) if ((start = _content.find_first_not_of(" \t\n", *curr)) == std::string::npos) throw std::invalid_argument("bad config file arguments"); -// std::cout << "start + 4 = " << _content.substr(start, 4) << "\n"; -// std::cout << "curr + 4 = " << _content.substr(*curr, 4) << "\n"; - - if ((*curr = _content.find_first_of("\n", start)) == std::string::npos) throw std::invalid_argument("bad config file arguments"); std::string values = _content.substr(start, *curr - start); - -// std::cout << "rest of Line values: " << values << "\n"; - return (values); } @@ -90,4 +78,3 @@ void ConfigParser::_print_content() const std::cout << _content; } -// I might need to make my own Exceptions to throw... diff --git a/srcs/config/parser.cpp b/srcs/config/parser.cpp index c804b86..94445bd 100644 --- a/srcs/config/parser.cpp +++ b/srcs/config/parser.cpp @@ -145,10 +145,9 @@ LocationConfig ConfigParser::_parse_location(size_t *start) ret.allow_methods = 0; ret.path = _get_first_word(&curr); -// are you sure about this? if (ret.path[0] != '/') - ret.path.insert(0, "/"); -// throw std::invalid_argument("Location path require a leading /"); + throw std::invalid_argument("Location path require a leading /"); + // ret.path.insert(0, "/"); // in theory now curr should be right after the "path" curr = _content.find_first_not_of(" \t\n", curr); @@ -158,7 +157,6 @@ LocationConfig ConfigParser::_parse_location(size_t *start) if ((curr = _content.find_first_of(" \t\n", curr + 1)) == std::string::npos) throw std::invalid_argument("bad config file syntax"); - // are there other things to check for? while (curr != std::string::npos) { // so this moves curr to past the word... @@ -181,9 +179,11 @@ LocationConfig ConfigParser::_parse_location(size_t *start) +// should i be sending pointers or references? void ConfigParser::_set_server_values(ServerConfig *server, \ const std::string key, std::string value) { +// should i be sending pointers or references? value = _pre_set_val_check(key, value); std::vector tmp_val = ::split(value, ' '); @@ -206,7 +206,6 @@ void ConfigParser::_set_server_values(ServerConfig *server, \ { if (tmp_val[0].find_first_of(":") == std::string::npos) { - // should i limit which ports can be used? if (!::isNumeric(tmp_val[0])) throw std::invalid_argument("bad port number"); server->host = "0.0.0.0"; @@ -246,31 +245,19 @@ void ConfigParser::_set_server_values(ServerConfig *server, \ } else if (key == "index") { - // i think you can call index several times... for (unsigned long i = 0; i != tmp_val.size(); i++) server->index.push_back(tmp_val[i]); } else if (key == "error_page") { - - // so it can either be just a /here/is/the/repo - // or it can be http://some_domain.com/here - // wtf... how should we handle... - - - - // you can definitely call Error_pages several times, i think std::string path = tmp_val[tmp_val.size() - 1]; for (unsigned long i = 0; i != tmp_val.size() - 1; i++) { - // what are the bounds for Error codes? - if (!(isNumeric_btw(0, 600, tmp_val[i]))) - throw std::invalid_argument("value not a valid number"); + if (!(isNumeric_btw(400, 599, tmp_val[i]))) + throw std::invalid_argument("invalid error code"); int status_code = atoi(tmp_val[i].c_str()); - - // yea cuz here we continue.. why suddenly flexible not throw ? if (server->error_pages.find(status_code) != server->error_pages.end()) - continue ; + throw std::invalid_argument("redeclaring error page"); server->error_pages[status_code] = path; } } @@ -279,9 +266,11 @@ void ConfigParser::_set_server_values(ServerConfig *server, \ } +// should i be sending pointers or references? void ConfigParser::_set_location_values(LocationConfig *location, \ const std::string key, std::string value) { +// should i be sending pointers or references? value = _pre_set_val_check(key, value); std::vector tmp_val = ::split(value, ' '); @@ -297,14 +286,9 @@ void ConfigParser::_set_location_values(LocationConfig *location, \ location->root = tmp_val[0]; } else if (key == "autoindex" && size == 1) - { location->autoindex = (tmp_val[0] == "on" ? true : false); - std::cout << "in parser " << location->path << " autoindex: " << location->autoindex << '\n'; - } else if (key == "index") { - // what about index /index.html; aka at the root? not handle? - // you can definitely call Index several times, i think for (unsigned long i = 0; i != tmp_val.size(); i++) location->index.push_back(tmp_val[i]); } @@ -330,28 +314,27 @@ void ConfigParser::_set_location_values(LocationConfig *location, \ else if (key == "redirect" && location->redirect_status == 0 \ && location->redirect_uri == "") { -// actually i think there can only be one per location... - // you can definitely call return several times, i think if (tmp_val.size() != 2) throw std::invalid_argument("wrong number of values"); - // and tmp_val[0] should be a number and tmp_val[1] a string? if (tmp_val[0] != "301" && tmp_val[0] != "302" && tmp_val[0] != "303" && tmp_val[0] != "307" && tmp_val[0] != "308") throw std::invalid_argument("bad redirect status"); -// double check this - // it means we aren't allowing internal redirects. + std::cout << tmp_val[1] << '\n'; if (tmp_val[1].compare(0, 7, "http://") - || tmp_val[1].compare(0, 8, "https://")) + && tmp_val[1].compare(0, 8, "https://")) throw std::invalid_argument("bad redirect uri"); location->redirect_status = atoi(tmp_val[0].c_str()); location->redirect_uri = tmp_val[1]; } - else if (key == "upload_repo" && size == 1 && location->upload_repo == "") + else if (key == "upload_dir" && size == 1 && location->upload_dir == "") { // what checks to do? - location->upload_repo = tmp_val[0]; + // add trailing / + if (tmp_val[0][tmp_val[0].size() - 1] != '/') + tmp_val[0].push_back('/'); + location->upload_dir = tmp_val[0]; } else throw std::invalid_argument("bad key value pair"); diff --git a/srcs/config/postProcessing.cpp b/srcs/config/postProcessing.cpp index e193549..544d0a4 100644 --- a/srcs/config/postProcessing.cpp +++ b/srcs/config/postProcessing.cpp @@ -55,26 +55,16 @@ void ConfigParser::_post_processing(std::vector *servers) if (it_l->index.empty()) it_l->index = it->index; - // same for redirect status i think + // nothing to be done for cgi_ext, error_pages, redirect - // 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) - { - //either we throw or we erase - 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; } std::sort(it->locations.begin(), it->locations.end()); -// std::reverse(it->locations.begin(), it->locations.end()); + std::reverse(it->locations.begin(), it->locations.end()); ++it; } diff --git a/srcs/webserv/response.cpp b/srcs/webserv/response.cpp index 76578f4..3e3820a 100644 --- a/srcs/webserv/response.cpp +++ b/srcs/webserv/response.cpp @@ -230,7 +230,7 @@ else { if (it->path.size() == path.size()) break; - else if (path[it->path.size()] == '/') + else if (path[it->path.size() - 1] == '/') break; } ++it; @@ -260,13 +260,103 @@ if no path coresponds then use the most correct one the point we are aiming for */ + for (std::vector::const_iterator it = server.locations.begin(); it != server.locations.end(); it++) + { + std::cout << it->path << " -- "; +// std::cout << it->path[it->path.size() - 1] << " "; +// it->path.size() -1 only when path ends in / because +// if path doesn't end in / then we are looking for a file +// meaning all it->paths that end in / are wrong if they >= + // if (it->path[it->path.size() - 1] == '/' ? it->path.size() - 1 > path.size() : it->path.size() > path.size()) + if (path[path.size() - 1] == '/' ? it->path.size() > path.size() : it->path.size() - 1 > path.size()) + { + std::cout << "skipping this one\n"; + continue ; + } + +// if (it->path.size() > path.size()) // Warning : il faut aussi prendre en compte l'éventuel "/" final +// continue; + + +// IS THERE A WAY TO SIMPLIFY THIS LOGIC ??? + + +// if (it->path[it->path.size() - 1] == '/') + if (path[path.size() - 1] == '/') + { + if (path.compare(0, it->path.size(), it->path) == 0) + { + std::cout << "checking with last /\n"; + if (it->path.size() == path.size()) + { + std::cout << "path sizes are equal \n"; + return (&(*it)); + } + else if (path[it->path.size() - 1] == '/') + { + std::cout << "ends in /\n"; + return (&(*it)); + } + } + } + else + { + if (path.size() < it->path.size()) + { + std::cout << "path is missing a /\n"; + if (it->path.compare(0, path.size(), path) == 0) + return (&(*it)); + // means we are looking for /test/test_deeper/ + // with /test/test_deeper + } + else + { +// if (it->path.compare(0, it->path.size() - 1, path) == 0) + if (path.compare(0, it->path.size(), it->path) == 0) + { + std::cout << "checking without last /\n"; + if (it->path.size() - 1 == path.size()) + return (&(*it)); + else if (path[it->path.size() - 1] == '/') + return (&(*it)); + } + } + } +// /test/mdr +// /test/mdr/ +// /test/mdrBST + +/* More stuff to check this still works with *** + +/test/test_ +/test/test_/ +/test/test_deeper +/test/test_deeper/ +/test/test_deepei +/test/test_deepei/ +/test/test_deeperi + + +*/ + + + + + } +// if (it != server.locations.end()) +// return (&(*it)); +// else + return (&(server.locations.back())); + + +/* std::vector::const_iterator best; std::cout << "\nMade it to weird location picker case.\n"; for (std::vector::const_iterator it = server.locations.begin(); it != server.locations.end(); it++) { - std::cout << it->path << " -- "; +*/ // if (rit->path.size() > path.size()) /* if ((rit->path[rit->path.size() - 1] == '/' ? rit->path.size() : rit->path.size() - 1) > path.size()) { @@ -292,7 +382,7 @@ if no path coresponds then use the most correct one // compare everything // - if (it->path[it->path.size() - 1] == '/' +/* if (it->path[it->path.size() - 1] == '/' && it->path.compare(0, it->path.size() - 1, path) == 0) { best = it; @@ -313,6 +403,7 @@ if no path coresponds then use the most correct one // //test.comare(0, 5, /test/something) // /test /test/something return (&(*best)); +*/ } std::string Webserv::_determine_file_extension(const std::string &path) const diff --git a/www/error_pages/error_404.html b/www/error_pages/error_404.html new file mode 100644 index 0000000..fa18a2b --- /dev/null +++ b/www/error_pages/error_404.html @@ -0,0 +1,11 @@ + + + + 404 Not Found + + +

Check it UP 404 Not Found

+
+

Le Webserv/0.1

+ + diff --git a/www/test/index1.html b/www/test/index1.html index cf2702d..f976302 100644 --- a/www/test/index1.html +++ b/www/test/index1.html @@ -3,7 +3,7 @@ Webserv test index - +