diff --git a/Makefile b/Makefile index b8324f3..3e4486d 100644 --- a/Makefile +++ b/Makefile @@ -19,14 +19,13 @@ HEADERS = Webserv.hpp \ LocationConfig.hpp \ Client.hpp \ Server.hpp \ + MethodType.hpp \ DEPENDENCIES = $(HEADERS:%=$(HEADERS_D)/%) SRCS = main.cpp \ Webserv.cpp \ ConfigParser.cpp \ - ServerConfig.cpp \ - LocationConfig.cpp \ DIR_OBJS = builds diff --git a/srcs/ConfigParser.cpp b/srcs/ConfigParser.cpp index 15d3c0c..d1144e9 100644 --- a/srcs/ConfigParser.cpp +++ b/srcs/ConfigParser.cpp @@ -90,9 +90,10 @@ ConfigParser & ConfigParser::operator=(const ConfigParser& rhs) */ -std::vector ConfigParser::parse() +std::vector * ConfigParser::parse() { - std::vector ret; + std::vector * ret = new std::vector(); +// std::vector ret; size_t start = 0; size_t curr = _content.find_first_not_of(" \t\n", 0); @@ -105,19 +106,19 @@ std::vector ConfigParser::parse() // if not here do i need them elsewhere? start = _content.find_first_not_of(" \t\n", curr); curr = _content.find_first_of(" \t\n", start); - std::string key = _conent.substr(start, curr - start); + std::string key = _content.substr(start, curr - start); if (key != "server") throw std::invalid_argument("bad config file arguments"); // Server server = parse_server(&curr); // ret->push_back(server); // why not this? - ret.push_back(parse_server(&curr); + ret->push_back(_parse_server(&curr)); } return (ret); } // might need new names for Prev and Curr, not super descriptive... -ServerConfig ConfigParser::parse_server(size_t *start) +ServerConfig ConfigParser::_parse_server(size_t *start) { ServerConfig ret; size_t curr = _content.find_first_not_of(" \t\n", *start); @@ -133,21 +134,24 @@ ServerConfig ConfigParser::parse_server(size_t *start) // so this moves curr to past the word... std::string key = _get_first_word(&curr); // now curr is on space after 1st word. - switch (key) + if (key == "}") { - case "}": - // why +1 curr is already after it no? - *start = _content.find_first_not_of(" \t\n" curr + 1); - break ; - case "location": - // this does assume we have locations in Server... - // could change the name but it's so clear... - ret.location.push_back(_parse_location(&curr)); - default: - std::string values = _get_rest_of_line(&curr); - // curr now should be \n - // checking for ; in _set_value, check key and value - _set_server_values(&ret, key, values); // handles the throws + // why +1 curr is already after it no? + *start = _content.find_first_not_of(" \t\n", curr + 1); + break ; + } + else if (key == "location") + { + // this does assume we have locations in Server... + // could change the name but it's so clear... + ret.locations.push_back(_parse_location(&curr)); + } + else + { + std::string values = _get_rest_of_line(&curr); + // curr now should be \n + // checking for ; in _set_value, check key and value + _set_server_values(&ret, key, values); // handles the throws } } return (ret); @@ -163,7 +167,7 @@ LocationConfig ConfigParser::_parse_location(size_t *start) if (curr == std::string::npos || _content[curr] != '{') throw std::invalid_argument("bad config file syntax"); - size_t curr = _content.find_first_of(" \t\n", curr + 1); + curr = _content.find_first_of(" \t\n", curr + 1); // if (curr == std::string::npos) // are there other things to check for? // throw std::invalid_argument("bad config file syntax"); while (curr != std::string::npos) @@ -171,17 +175,18 @@ LocationConfig ConfigParser::_parse_location(size_t *start) // so this moves curr to past the word... std::string key = _get_first_word(&curr); // now curr is on space after 1st word. - switch (key) + if (key == "}") { - case "}": - *start = curr; - break ; - default: - std::string values = _get_rest_of_line(&curr); - // curr now should be \n - // checking for ; in _set_value, check key and value + *start = curr; + break ; + } + else + { + std::string values = _get_rest_of_line(&curr); + // curr now should be \n + // checking for ; in _set_value, check key and value - _set_location_values(&ret, key, values); //handles the throws + _set_location_values(&ret, key, values); //handles the throws } } return (ret); @@ -223,94 +228,112 @@ void ConfigParser::_set_server_values(ServerConfig *server, \ // like call substr in split? value = value.substr(0, i - 1); - std::vector tmp_val = ::split(value, ' '); + std::vector tmp_val = split(value, ' '); if (tmp_val.size() == 1) { - switch (key) + if (key == "server_name") { - case "server_name": - server->server_name = tmp_val[0]; - case "listen": - if (tmp_val[0].find_first_of(":") == std::string::npos) - { - // why not store as vector [4] ? - server->host = "0.0.0.0"; - server->value = tmp_val[0]; - } - else - { - // maybe do this differently? - std::vector tmp2 = split(tmp_val[0], ':'); - // i might take issue with this, will see - if (server->host != "" && server->host != tmp2[0]) - throw std::invalid_argument("bad listen"); - server->host = tmp2[0]; - server->port = tmp2[1]; - } - case "root": - server->root = tmp_val[0]; - case "autoindex": - server->autoindex = (tmp_val[0] == "on" ? true : false); - case "client_body_limit": - server->client_body_limit = atoi(tmp_val[0].c_str()); - - case "recv_timeout": - // what is tv_sec and do i need it? + server->server_name = tmp_val[0]; + } + else if (key == "listen") + { + if (tmp_val[0].find_first_of(":") == std::string::npos) + { + // why not store as vector [4] ? + server->host = "0.0.0.0"; + server->port = tmp_val[0]; + } + else + { + // maybe do this differently? + std::vector tmp2 = split(tmp_val[0], ':'); + // i might take issue with this, will see + if (server->host != "" && server->host != tmp2[0]) + throw std::invalid_argument("bad listen"); + server->host = tmp2[0]; + server->port = tmp2[1]; + } + } + else if (key == "root") + { + server->root = tmp_val[0]; + } + else if (key == "autoindex") + { + server->autoindex = (tmp_val[0] == "on" ? true : false); + } + else if (key == "client_body_limit") + { + server->client_body_limit = atoi(tmp_val[0].c_str()); + } + else if (key == "recv_timeout") + { + // what is tv_sec and do i need it? // ok so i don't fully understand this part but ok, keep for now... - server->recv_timeout.tv_sec = atoi(tmp_val[0].c_str()); - case "send_timeout": - server->send_timeout.tv_sec = atoi(tmp_val[0].c_str()); - - default : - throw std::invalid_argument("should only have 1 value"); + server->recv_timeout.tv_sec = atoi(tmp_val[0].c_str()); + } + else if (key == "send_timeout") + { + server->send_timeout.tv_sec = atoi(tmp_val[0].c_str()); + } + else + { + throw std::invalid_argument("should only have 1 value"); // yea ok but it could also be something else like too many // args + } } else if (tmp_val.size() > 1) { - switch (key) + if (key == "index") { - case "index": - // could run more tests on value content but meh... - for (unsigned long i = 0; i != tmp_val.size(); i++) - server->index.push_back(tmp_val[i]); - case "allow_methods": - // might do something different here - // like change how methods are stored? - for (unsigned long i = 0; i != tmp_val.size(); i++) - server->allow_methods.push_back(_str_to_method_type(tmp_val[i])); - case "return": - // could run more checks here too - // like tmp_val.size() must be 2 - // and tmp_val[0] should be a number and tmp_val[1] a string? - server->redirect_status = atoi(tmp_val[0].c_str()); - server->redirect_uri = tmp_val[1]; - case "error_page": - // something more complicated? - // like make sure ints then 1 string? - std::string path = tmp_val[tmp_val.size() - 1]; - for (unsigned long i = 0; i != tmp_val.size() - 1; i++) - { - int status_code = atoi(tmp_val[i].c_str()); - // yea IDK i might not want to store this like that... - if (server->error_pages.find(status_code) != server->error_pages.end()) - continue ; - server->error_pages[status_code] = path; - } - default : - throw std::invalid_argument("wrong number of values"); + // could run more tests on value content but meh... + for (unsigned long i = 0; i != tmp_val.size(); i++) + server->index.push_back(tmp_val[i]); + } + else if (key == "allow_methods") + { + // might do something different here + // like change how methods are stored? + for (unsigned long i = 0; i != tmp_val.size(); i++) + server->allow_methods.push_back(_str_to_method_type(tmp_val[i])); + } + else if (key == "return") + { + // could run more checks here too + // like tmp_val.size() must be 2 + // and tmp_val[0] should be a number and tmp_val[1] a string? + server->redirect_status = atoi(tmp_val[0].c_str()); + server->redirect_uri = tmp_val[1]; + } + else if (key == "error_page") + { + // something more complicated? + // like make sure ints then 1 string? + std::string path = tmp_val[tmp_val.size() - 1]; + for (unsigned long i = 0; i != tmp_val.size() - 1; i++) + { + int status_code = atoi(tmp_val[i].c_str()); + // yea IDK i might not want to store this like that... + if (server->error_pages.find(status_code) != server->error_pages.end()) + continue ; + server->error_pages[status_code] = path; + } + } + else + { + throw std::invalid_argument("wrong number of values"); } } else throw std::invalid_argument("missing value"); - } // again not sure i want an int ret -int ConfigParser::_set_location_values(LocationConfig *location, \ - const std::string key, std::string value) +void ConfigParser::_set_location_values(LocationConfig *location, \ + const std::string key, std::string value) { // check key for ; // check values for ; at end and right number of words depending on key @@ -341,37 +364,44 @@ int ConfigParser::_set_location_values(LocationConfig *location, \ if (tmp_val.size() == 1) { - switch (key) + if (key == "root") { - case "root": - location->root = tmp_val[0]; - case "client_body_limit": - location->client_body_limit = atoi(tmp_val[0].c_str()); - default : - throw std::invalid_argument("should only have 1 argument"); + location->root = tmp_val[0]; + } + else if (key == "client_body_limit") + { + location->client_body_limit = atoi(tmp_val[0].c_str()); + } + else + { + throw std::invalid_argument("should only have 1 argument"); } } else if (tmp_val.size() > 1) { - switch (key) + if (key == "index") + { + for (unsigned long i = 0; i != tmp_val.size(); i++) + location->index.push_back(tmp_val[i]); + } + else if (key == "allow_methods") + { + for (unsigned long i = 0; i != tmp_val.size(); i++) + location->allow_methods.push_back(_str_to_method_type(tmp_val[i])); + } + else if (key == "cgi_info") { - case "index": - for (unsigned long i = 0; i != tmp_val.size(); i++) - location->index.push_back(tmp_val[i]); - case "allow_methods": - for (unsigned long i = 0; i != tmp_val.size(); i++) - location->allow_methods.push_back(_str_to_methodtype(tmp_val[i])); - case "cgi_info": // ok wtf is all this even doing, figure that out - unsigned long i = value.find_first_of(" "); - if (i == std::string::npos) - throw std::invalid_argument("bad config file arguments"); - // ok why an int now, we gotta be more consistent! - int j = value.find_first_not_of(" ", i); - location->cgi_info[value.substr(0, i)] = value.substr(j, value.length()); - default : + unsigned long i = value.find_first_of(" "); + if (i == std::string::npos) throw std::invalid_argument("bad config file arguments"); - + // ok why an int now, we gotta be more consistent! + int j = value.find_first_not_of(" ", i); + location->cgi_info[value.substr(0, i)] = value.substr(j, value.length()); + } + else + { + throw std::invalid_argument("bad config file arguments"); } } else @@ -412,23 +442,20 @@ std::string ConfigParser::_get_rest_of_line(size_t *curr) } -MethodType ConfigParser::_str_to_methodtype(std::string str) +MethodType ConfigParser::_str_to_method_type(std::string str) { - switch (str) - { - case ("GET"): - return GET; - case ("POST"): - return POST; - case ("DELETE"): - return DELETE; - default : - return INVALID; - } + if (str == "GET") + return GET; + else if (str == "POST") + return POST; + else if (str == "DELETE") + return DELETE; + return INVALID; } + void ConfigParser::_print_content() const { std::cout << _content; diff --git a/srcs/ConfigParser.hpp b/srcs/ConfigParser.hpp index 8ef686a..81b1cdf 100644 --- a/srcs/ConfigParser.hpp +++ b/srcs/ConfigParser.hpp @@ -14,6 +14,7 @@ # define CONFIGPARSER_HPP # include "Webserv.hpp" // easier to just do this? +# include "ServerConfig.hpp" // add includes properly @@ -22,6 +23,8 @@ #define MAX_URI_SIZE 64 #define BSIZE 1024 +/* +// this can't be here... enum MethodType { GET, @@ -29,7 +32,7 @@ enum MethodType DELETE, INVALID, }; - +*/ class ConfigParser { @@ -45,11 +48,14 @@ public: // ConfigParser & operator=(const ConfigParser& rhs); // void parse(); // return void cuz throw exceptions. - //std::vector * parse(); // const? - std::vector parse(); // const? + std::vector * parse(); // const? +// std::vector parse(); // const? // other parses? +// i thought if it were an instance of this class you could call +// private member functions from anywhere... + void _print_content() const; private: std::string _content; @@ -76,7 +82,6 @@ private: static MethodType _str_to_method_type(std::string str); // just for testing purposes - void _print_content() const; }; diff --git a/srcs/MethodType.hpp b/srcs/MethodType.hpp new file mode 100644 index 0000000..9c815f5 --- /dev/null +++ b/srcs/MethodType.hpp @@ -0,0 +1,15 @@ + + +#ifndef METHODTYPE_HPP +# define METHODTYPE_HPP + +enum MethodType +{ + GET, + POST, + DELETE, + INVALID, +}; + + +#endif diff --git a/srcs/ServerConfig.hpp b/srcs/ServerConfig.hpp index a6cdc6b..a08d8a1 100644 --- a/srcs/ServerConfig.hpp +++ b/srcs/ServerConfig.hpp @@ -15,6 +15,8 @@ // add includes properly... # include "Webserv.hpp" +# include "MethodType.hpp" +//# include "ConfigParser.hpp" # include "LocationConfig.hpp" // a class that's all public? just so we have options? @@ -63,13 +65,16 @@ public: std::cout << "Server_name: " << server_name << '\n'; std::cout << "root: " << root << '\n'; std::cout << "index: "; - for (int i = 0; i < index.size(); i++) + for (size_t i = 0; i < index.size(); i++) std::cout << index[i] << " "; std::cout << "\nerror_pages: "; - for (int i = 0; i < error_pages.size(); i++) - std::cout << error_pages.first << "--" << error_pages.second << " "; + for(std::map::iterator it = error_pages.begin(); \ + it != error_pages.end(); it++) + std::cout << it->first << "--" << it->second << " "; +// for (size_t i = 0; i < error_pages.size(); i++) +// std::cout << error_pages->first << "--" << error_pages->second << " "; std::cout << "\nallow_methods: "; - for (int i = 0; i < allow_methods.size(); i++) + for (size_t i = 0; i < allow_methods.size(); i++) std::cout << allow_methods[i] << " "; std::cout << "\nskiping Locations for now...\n"; std::cout << "also skiping send_timeout and recv\n"; diff --git a/srcs/Webserv.cpp b/srcs/Webserv.cpp index b98c685..b26964d 100644 --- a/srcs/Webserv.cpp +++ b/srcs/Webserv.cpp @@ -28,6 +28,8 @@ Webserv::Webserv() } */ +// we'll come back to this +/* Webserv::Webserv(std::vector* servers) : _servers(servers) { @@ -42,6 +44,7 @@ Webserv::Webserv(std::vector* servers) throw std::runtime_error("Epoll init"); } } +*/ Webserv::~Webserv() { diff --git a/srcs/Webserv.hpp b/srcs/Webserv.hpp index 68345b6..2eebbaf 100644 --- a/srcs/Webserv.hpp +++ b/srcs/Webserv.hpp @@ -25,7 +25,15 @@ # include "Client.hpp" # include "Server.hpp" +# include "ConfigParser.hpp" +# include "ServerConfig.hpp" +# include "LocationConfig.hpp" +# include "MethodType.hpp" # include // signal +# include +# include +# include +# include # define BUFSIZE 8192 # define TIMEOUT 3000 @@ -63,7 +71,7 @@ class Webserv // Webserv(Webserv const &src); // what should it take as arg, *, &, ? - Webserv(std::vector& servers); +// Webserv(std::vector& servers); ~Webserv(); // Webserv &operator=(Webserv const &rhs); diff --git a/srcs/main.cpp b/srcs/main.cpp index 7cf49d9..5495a18 100644 --- a/srcs/main.cpp +++ b/srcs/main.cpp @@ -20,10 +20,10 @@ int main(int ac, char **av) configParser._print_content(); - std::vector servers = configParser.parse(); +// std::vector* servers = configParser.parse(); - for (int i = 0; i < server.size(); i++) - servers[i].print_all(); +// for (size_t i = 0; i < servers->size(); i++) +// servers[i]->print_all(); // Webserv serv(configParser.parse()); // is this better or worse than using