Index and Autoindex work nicely, standarized way paths for root and location path are stored in config, still needs a little polishing prolly

This commit is contained in:
Me
2022-08-08 02:50:37 +02:00
parent cf69168a84
commit 9ee7205b95
13 changed files with 99 additions and 173 deletions

View File

@@ -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<std::string> index;
unsigned int allow_methods;
std::vector<std::string> cgi_ext; // php not .php
bool autoindex;
bool autoindex;
std::vector<std::string> 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 <= ?
};

View File

@@ -14,44 +14,24 @@
class ServerConfig
{
public:
// do i need some canonic stuff?
// there can be several
std::vector<std::string> 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<std::string> index;
std::map<int, std::string> error_pages;
// fuck it, you can only call allow_methods once in Server
std::vector<LocationConfig> 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()
{

View File

@@ -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");
}
}

View File

@@ -57,7 +57,7 @@ void ConfigParser::_post_processing(std::vector<ServerConfig> *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<ServerConfig> *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;
}

View File

@@ -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);
}

View File

@@ -24,6 +24,7 @@
# include <string> // string
# include <cstdio> // perror, remove
# include <cstdlib> // atoi (athough it's already cover by <string>)
# include <dirent.h> // opendir()
# include "Client.hpp"
# include "ServerConfig.hpp"

View File

@@ -8,7 +8,7 @@
"<!DOCTYPE html>"\
"<html>"\
"<head>"\
"<title> Index of "
"<title>Index of "
# define AUTOINDEX_MID1 \
"</title>"\

View File

@@ -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 <stdio.h>
#include <dirent.h>
// 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("<a href=\"");
dir_list.append(location.path.c_str());
// if no / at end of location path...
if (location.path.find_last_of("/") != location.path.size())
dir_list.append("/");
dir_list.append(ent->d_name);
dir_list.append("\">");
dir_list.append(ent->d_name);
dir_list.append("</a>");
dir_list.append("\r\n");
dir_list.append("\r\n"); // is this right?
}
// <a href="http://nginx.org/">nginx.org</a>.<br/>
// <a href="/test/test_deeper/index1.html">index1.html</a>
// apparently this is more than good enough!
// <a href="/test/test_deeper/..">..</a>
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())