ok Location sorting and processing is finally working as expected, still a few things to add like error_pages but will get there soon

This commit is contained in:
Me
2022-08-05 21:46:46 +02:00
parent 9ac14aa1aa
commit f7dc5ccde4
12 changed files with 119 additions and 114 deletions

View File

@@ -106,6 +106,13 @@ public:
// 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 << "locations are equal\n";
std::string tmp_path_lhs = root + path;
std::cout << "root + path: " << tmp_path_lhs << '\n';
@@ -132,6 +139,7 @@ public:
--comp_rhs;
}
// do i need to free c_path's ???
*/
}

View File

@@ -82,6 +82,9 @@ std::string ConfigParser::_get_rest_of_line(size_t *curr)
return (values);
}
void ConfigParser::_print_content() const
{
std::cout << _content;

View File

@@ -85,10 +85,11 @@ std::vector<ServerConfig> * ConfigParser::parse()
throw std::invalid_argument("empty config file");
while (curr != std::string::npos)
{
// why no checks here
// 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);
if ((start = _content.find_first_not_of(" \t\n", curr)) == std::string::npos)
throw std::invalid_argument("empty config file");
if ((curr = _content.find_first_of(" \t\n", start)) == std::string::npos)
throw std::invalid_argument("empty config file");
std::string key = _content.substr(start, curr - start);
if (key != "server")
throw std::invalid_argument("bad config file arguments 1");
@@ -109,9 +110,9 @@ ServerConfig ConfigParser::_parse_server(size_t *start)
if (curr == std::string::npos || _content[curr] != '{')
throw std::invalid_argument("bad config file syntax 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");
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) // here curr == { + 1
{
// so this moves curr to past the word...
@@ -147,8 +148,6 @@ LocationConfig ConfigParser::_parse_location(size_t *start)
ret.redirect_status = 0;
ret.allow_methods = 0;
// path must have a leading / else move on to next location
// i guess we'll be strict cuz can't return (NULL); or NUL...
ret.path = _get_first_word(&curr);
if (ret.path[0] != '/')
throw std::invalid_argument("Location path require a leading /");
@@ -159,9 +158,9 @@ LocationConfig ConfigParser::_parse_location(size_t *start)
if (curr == std::string::npos || _content[curr] != '{')
throw std::invalid_argument("bad config file syntax 2");
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");
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...
@@ -183,8 +182,6 @@ LocationConfig ConfigParser::_parse_location(size_t *start)
}
#include <stdio.h>
void ConfigParser::_set_server_values(ServerConfig *server, \
const std::string key, std::string value)
@@ -198,12 +195,9 @@ void ConfigParser::_set_server_values(ServerConfig *server, \
throw std::invalid_argument("missing value");
else if (key == "server_name" && server->server_name.empty())
{
// fuck should i be using an iterator?
// for (size_t i = 0; i < server->server_name.size(); i++)
for (std::vector<std::string>::iterator it = server->server_name.begin(); \
it < server->server_name.end(); it++)
{
// if (server->server_name[i].compare(tmp_val[0]) == 0)
if (it->compare(tmp_val[0]) == 0)
throw std::invalid_argument("server_name already exists");
}
@@ -243,44 +237,11 @@ void ConfigParser::_set_server_values(ServerConfig *server, \
if (tmp_val[0][0] != '/')
throw std::invalid_argument("Root requires leading /");
// unclear if this is always true? might only be true in Server
// but not in Locations? idk...
//i think it does, i must have read wrong somewhere...
// don't bother using lstat
// don't bother with include <errno.h> for now.
// std::cout << tmp_val[0] << '\n';
// should i also check that it's not a file? no i think S_ISDIR does that right?
const char* folder = tmp_val[0].substr(1).c_str();
struct stat sb;
printf("folder:%s\n", folder);
if (stat(folder, &sb) == 0 && S_ISDIR(sb.st_mode))
{
// std::cout << "is a Dir\n";
// std::cout << "root: " << tmp_val[0] << '\n';
if (path_is_valid(tmp_val[0]) == 1)
server->root = tmp_val[0];
}
else
throw std::invalid_argument("root dir could not be opened 1");
// do i need to free folder?
/* DIR* dir = opendir(tmp_val[0].c_str());
if (dir)
closedir(dir);
else
{
switch (errno) {
case EACCES: printf("Permission denied\n"); break;
case ENOENT: printf("Directory does not exist\n"); break;
case ENOTDIR: printf("is not a directory\n"); break;
default:
throw std::invalid_argument("root dir could not be opened 1");
}
}
*/
throw std::invalid_argument("Root dir invalid 1");
}
else if (key == "autoindex" && size == 1)
{
@@ -338,17 +299,7 @@ void ConfigParser::_set_server_values(ServerConfig *server, \
server->error_pages[status_code] = path;
}
}
/* else if (key == "recv_timeout" && size == 1 && server->server_name == "")
{
// 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());
}
else if (key == "send_timeout" && size == 1 && server->server_name == "")
{
server->send_timeout.tv_sec = atoi(tmp_val[0].c_str());
}
*/ else
else
{
// means either you didn't write the right key, or the value is
// missing, or the value has already been filled.
@@ -369,19 +320,14 @@ void ConfigParser::_set_location_values(LocationConfig *location, \
throw std::invalid_argument("missing value");
else if (key == "root" && size == 1 && location->root == "")
{
// std::cout << "location root: " << tmp_val[0] << '\n';
if (tmp_val[0][0] != '/')
throw std::invalid_argument("Root requires leading /");
const char* folder = tmp_val[0].substr(1).c_str();
struct stat sb;
if (stat(folder, &sb) == 0 && S_ISDIR(sb.st_mode))
{
// std::cout << "is a Dir\n";
if (path_is_valid(tmp_val[0]) == 1)
location->root = tmp_val[0];
}
else
throw std::invalid_argument("root dir could not be opened");
throw std::invalid_argument("Root dir invalid");
}
else if (key == "client_body_limit" && size == 1 \
&& location->client_body_limit == 0)

View File

@@ -57,27 +57,8 @@ void ConfigParser::_post_processing(std::vector<ServerConfig> *servers)
std::vector<LocationConfig>::iterator it_l = it->locations.begin();
// first check locations we have
while (it_l != it->locations.end())
{
// opendir() doesn't work for some reason...
// this doens't work yet cuz the path needs to be relative and stat doesn't like / before...
const char* folder = it_l->path.substr(1).c_str();
struct stat sb;
// wait also have to add checks in for files!
// also need to add the root to the path!!!!!!!! see LocationConfig and parser
if (stat(folder, &sb) == 0 && S_ISDIR(sb.st_mode))
{
// std::cout << "is a Dir\n";
// it_l->path = it_lpath;
// yea nothing happens, i guess i can change how the if conditions work...
}
else
throw std::invalid_argument("location dir could not be opened");
if (it_l->client_body_limit == 0)
it_l->client_body_limit = 5000; // what is the recomended size?
@@ -97,26 +78,25 @@ void ConfigParser::_post_processing(std::vector<ServerConfig> *servers)
// maybe do something for Cgi_info?
// 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");
}
++it_l;
}
// ok we can sort in order and reverse...
std::cout << "made it to sorting...\n";
// std::cout << "made it to sorting...\n";
// std::sort(it->locations.begin(), it->locations.end(), compareLocationConfigs);
std::sort(it->locations.begin(), it->locations.end());
std::reverse(it->locations.begin(), it->locations.end());
++it;
}
// do the defaults at the end?
}
bool ConfigParser::_find_root_path_location(std::vector<LocationConfig> locations)

View File

@@ -86,3 +86,43 @@ std::string http_methods_to_str(unsigned int methods)
return (str);
}
int path_is_valid(std::string path)
{
std::string i_path = path.substr(1);
const char *tmp_path = i_path.c_str();
struct stat s;
if (stat(tmp_path, &s) == 0)
{
if (S_ISREG(s.st_mode))
{
// std::cout << "is a file\n";
return (2);
}
else if (S_ISDIR(s.st_mode))
{
// std::cout << "is a Dir\n";
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);
}

View File

@@ -6,6 +6,10 @@
# include <string>
# include <sstream>
# include <cstdlib> // atoi
# include <sys/stat.h> // stat()
# include <iostream> // tmp
// enum http_method
@@ -33,6 +37,6 @@ std::string itos(int n);
std::string trim(std::string str, char c);
http_method str_to_http_method(std::string &str);
std::string http_methods_to_str(unsigned int methods);
int path_is_valid(std::string path);
#endif