I really hope this is the last time we fix Location Picker, i think it's good it's pretty elegant, basically set root and location path to never have / at end and that made things easier

This commit is contained in:
Me
2022-08-11 02:01:24 +02:00
9 changed files with 82 additions and 241 deletions

View File

@@ -26,9 +26,11 @@ server {
location /test { location /test {
index index1.html subdex.html; index index1.html subdex.html;
root ./www/test/;
} }
location /test/index1.html { location /test/index1.html {
root ./www/test/;
index index1.html subdex.html; index index1.html subdex.html;
} }
@@ -38,19 +40,22 @@ server {
location /stylesheet/ { location /stylesheet/ {
# root ./www/../; # root ./www/../;
root ./; root ./styelsheet/;
} }
location /test/something.html { location /test/something.html {
# allow_methods DELETE; # allow_methods DELETE;
root ./www/test/;
} }
location /test/test_deeper/ { location /test/test_deeper/ {
# allow_methods # allow_methods
autoindex on; autoindex on;
root ./www/test/test_deeper/;
} }
location /test/test_deeper/super_deep { location /test/test_deeper/super_deep {
root ./www/test/test_deeper/super_deep/;
autoindex on; autoindex on;
} }

View File

@@ -1,11 +1,8 @@
IN 42 SUBJECT AND/OR PRIORITY : IN 42 SUBJECT AND/OR PRIORITY :
- Fix "href" in autoindex
- CGI - CGI
- chunked request (response not mandatory it seems) - chunked request (response not mandatory it seems)
- fix need for index and autoindex config
- Ecrire des tests ! - Ecrire des tests !
- "root" need to replace "location->path" part of "client.path"
replace up to the last "/" of the "location->path" part
(if its a folder this will be in fact the entire path)
- handle redirection (Work, but weird behavior need deeper test) - handle redirection (Work, but weird behavior need deeper test)
- upload files with config "upload_dir" - upload files with config "upload_dir"
- _determine_location() review (New version to complete and test) - _determine_location() review (New version to complete and test)

View File

@@ -1,14 +1,3 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ConfigParser.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/07/13 22:11:17 by me #+# #+# */
/* Updated: 2022/08/03 17:51:35 by lperrey ### ########.fr */
/* */
/* ************************************************************************** */
#include "ConfigParser.hpp" #include "ConfigParser.hpp"
@@ -232,9 +221,9 @@ void ConfigParser::_set_server_values(ServerConfig *server, \
else if (key == "root" && size == 1 && server->root == "") else if (key == "root" && size == 1 && server->root == "")
{ {
// remove trailing / // remove trailing /
if (tmp_val[0][tmp_val[0].size() - 1] != '/') if (tmp_val[0][tmp_val[0].size() - 1] == '/')
tmp_val[0].push_back('/'); tmp_val[0].erase(tmp_val[0].size() - 1, 1);
// tmp_val[0].erase(tmp_val[0].size() - 1, 1); // tmp_val[0].push_back('/');
server->root = tmp_val[0]; server->root = tmp_val[0];
} }
else if (key == "client_body_limit" && size == 1 \ else if (key == "client_body_limit" && size == 1 \
@@ -281,10 +270,10 @@ void ConfigParser::_set_location_values(LocationConfig *location, \
throw std::invalid_argument("missing value"); throw std::invalid_argument("missing value");
else if (key == "root" && size == 1 && location->root == "") else if (key == "root" && size == 1 && location->root == "")
{ {
// add trailing / // remove trailing /
if (tmp_val[0][tmp_val[0].size() - 1] != '/') if (tmp_val[0][tmp_val[0].size() - 1] == '/')
tmp_val[0].push_back('/'); tmp_val[0].erase(tmp_val[0].size() - 1, 1);
// tmp_val[0].erase(tmp_val[0].size() - 1, 1); // tmp_val[0].push_back('/');
location->root = tmp_val[0]; location->root = tmp_val[0];
} }
else if (key == "autoindex" && size == 1) else if (key == "autoindex" && size == 1)

View File

@@ -52,15 +52,17 @@ void ConfigParser::_post_processing(std::vector<ServerConfig> *servers)
if (it_l->allow_methods == UNKNOWN) if (it_l->allow_methods == UNKNOWN)
it_l->allow_methods = ANY_METHODS; it_l->allow_methods = ANY_METHODS;
// also
if (it_l->index.empty() && it_l->autoindex == false) if (it_l->index.empty() && it_l->autoindex == false)
it_l->index = it->index; it_l->index = it->index;
// nothing to be done for cgi_ext, error_pages, redirect // nothing to be done for cgi_ext, error_pages, redirect
if (path_is_valid(it_l->root + it_l->path) == 1 \ // if (path_is_valid(it_l->root) == IS_DIR
&& it_l->path[it_l->path.size() - 1] != '/') // && it_l->path[it_l->path.size() - 1] != '/')
it_l->path.push_back('/'); // it_l->path.push_back('/');
if (it_l->path[it_l->path.size() - 1] == '/'
&& it_l->path.size() > 1)
it_l->path.erase(it_l->path.size() - 1);
++it_l; ++it_l;
} }

View File

@@ -117,16 +117,16 @@ int path_is_valid(std::string path)
if (S_ISREG(s.st_mode)) if (S_ISREG(s.st_mode))
{ {
// std::cout << "is a file\n"; // std::cout << "is a file\n";
return (2); return (IS_FILE);
} }
else if (S_ISDIR(s.st_mode)) else if (S_ISDIR(s.st_mode))
{ {
// std::cout << "is a Dir\n"; // std::cout << "is a Dir\n";
return (1); return (IS_DIR);
} }
} }
// std::cout << "path is neither dir nor file\n"; // std::cout << "path is neither dir nor file\n";
return (0); return (IS_OTHER);
} }

View File

@@ -14,6 +14,11 @@
# define LF "\n" # define LF "\n"
# define CRLF CR LF # define CRLF CR LF
# define IS_FILE 2
# define IS_DIR 1
# define IS_OTHER 0
enum http_method enum http_method
{ {
UNKNOWN = 0b0, UNKNOWN = 0b0,

View File

@@ -2,8 +2,6 @@
#ifndef AUTOINDEX_HPP #ifndef AUTOINDEX_HPP
# define AUTOINDEX_HPP # define AUTOINDEX_HPP
// # define HTML_ERROR(STATUS) "\r\n<!DOCTYPE html><html><head><title>"STATUS"</title></head><body><h1 style=\"text-align:center\">"STATUS"</h1><hr><p style=\"text-align:center\">Le Webserv/0.1</p></body></html>"
# define AUTOINDEX_START \ # define AUTOINDEX_START \
"<!DOCTYPE html>"\ "<!DOCTYPE html>"\
"<html>"\ "<html>"\

View File

@@ -1,68 +1,16 @@
#include "Webserv.hpp" #include "Webserv.hpp"
// TODO : path_is_valid() Macro for return value
void Webserv::_get(Client *client) void Webserv::_get(Client *client)
{ {
/* 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 ???
*/
std::string path = client->get_rq_abs_path(); std::string path = client->get_rq_abs_path();
// this might not be the best thing, a voir std::cerr << "path before = " << path << "\n"; // DEBUG
// path.insert(0, client->assigned_location->root);
//client->assigned_location->path
path.replace(0, client->assigned_location->path.size(), client->assigned_location->root); path.replace(0, client->assigned_location->path.size(), client->assigned_location->root);
std::cerr << "path after = " << path << "\n"; // DEBUG
std::cerr << "path = " << path << "\n"; // TMP HUGO ( We move this in process_switch() )
// 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.
// change this cuz
// if (path_is_valid(client->assigned_location->root) == 2)
// _get_file(...);
if (path_is_valid(path) == 1)
{
// std::cout << "path is valid\n";
if (path[path.size() - 1] != '/')
path.push_back('/');
for (size_t i = 0; i < client->assigned_location->index.size(); i++)
{
// std::cout << "location path: " << client->assigned_location->path << '\n';
// std::cout << "location index: " << client->assigned_location->index[i] << '\n';
// std::cout << "path with index: " << path + assigned_location->index[i] << '\n';
if (path_is_valid(path + client->assigned_location->index[i]) == 2)
{
// std::cout << "found a valid index\n";
path.append(client->assigned_location->index[i]);
_get_file(client, path);
return ;
}
}
if (client->assigned_location->autoindex == true)
{
_autoindex(client, path);
return ;
}
}
// else
// _get_file(client, path);
// what about cgi ???
// TMP HUGO
// //
std::string script_output; std::string script_output;
if (_is_cgi(client)) if (_is_cgi(client))
@@ -78,7 +26,28 @@ Where does cgi fit in in all this ???
// //
// END TMP HUGO // END TMP HUGO
// Index/Autoindex block
if (path_is_valid(path) == IS_DIR)
{
std::cout << "made it to Index/Autoindex\n";
if (path[path.size() - 1] != '/')
path.push_back('/');
for (size_t i = 0; i < client->assigned_location->index.size(); i++)
{
if (path_is_valid(path + client->assigned_location->index[i]) == 2)
{
path.append(client->assigned_location->index[i]);
_get_file(client, path); _get_file(client, path);
return ;
}
}
if (client->assigned_location->autoindex == true)
_autoindex(client, path);
}
else
_get_file(client, path);
} }
# define MAX_FILESIZE 1000000 // (1Mo) # define MAX_FILESIZE 1000000 // (1Mo)
@@ -147,9 +116,8 @@ void Webserv::_get_file(Client *client, const std::string &path)
//void Webserv::_autoindex(Client *client, LocationConfig &location, std::string &path) //void Webserv::_autoindex(Client *client, LocationConfig &location, std::string &path)
void Webserv::_autoindex(Client *client, std::string &path) void Webserv::_autoindex(Client *client, std::string &path)
{ {
// std::cout << "made it to _autoindex\n"; std::cout << "made it to _autoindex\n";
(void)path;
std::string dir_list; std::string dir_list;
DIR *dir; DIR *dir;
struct dirent *ent; struct dirent *ent;
@@ -157,21 +125,21 @@ void Webserv::_autoindex(Client *client, std::string &path)
// std::cout << "location root: " << client->assigned_location->root << " location path: " // std::cout << "location root: " << client->assigned_location->root << " location path: "
// << client->assigned_location->path << '\n'; // << client->assigned_location->path << '\n';
// if ((dir = opendir (path.c_str())) != NULL) std::cout << "Path in auto is: " << path << '\n';
if ((dir = opendir ((client->assigned_location->root + client->assigned_location->path).c_str())) != NULL) if ( (dir = opendir(path.c_str()) ) != NULL)
{ {
/* print all the files and directories within directory */ /* print all the files and directories within directory */
dir_list.append(AUTOINDEX_START); dir_list.append(AUTOINDEX_START);
dir_list.append(client->assigned_location->path); dir_list.append(path);
dir_list.append(AUTOINDEX_MID1); dir_list.append(AUTOINDEX_MID1);
dir_list.append(client->assigned_location->path); dir_list.append(path);
dir_list.append(AUTOINDEX_MID2); dir_list.append(AUTOINDEX_MID2);
while ((ent = readdir (dir)) != NULL) while ((ent = readdir (dir)) != NULL)
{ {
if (strcmp(".", ent->d_name) == 0) if (strcmp(".", ent->d_name) == 0)
continue ; continue ;
dir_list.append("<a href=\""); dir_list.append("<a href=\"");
dir_list.append(client->assigned_location->path.c_str()); // dir_list.append(path);
dir_list.append(ent->d_name); dir_list.append(ent->d_name);
dir_list.append("\">"); dir_list.append("\">");
dir_list.append(ent->d_name); dir_list.append(ent->d_name);

View File

@@ -169,67 +169,11 @@ ServerConfig *_determine_process_server(Client *client, std::vector<ServerConfig
return (&(*default_server)); return (&(*default_server));
} }
const LocationConfig *_determine_location_COOP_FIX(const ServerConfig &server, const std::string &path)
{
/* Pseudo-code :
- comparer les size(), si location.path > client.path, stop comparaison.
- client.path.compare(0, location.path.size(), location.path)
if ( == 0)
{
if (location.path.size() == client.path.size())
{
FOUND;
}
else if (client.path[location.path.size()] == '/')
{
FOUND;
}
}
else
{
NOT FOUND;
++next;
}
*/
std::vector<LocationConfig>::const_iterator it = server.locations.begin();
while (it != server.locations.end())
{
if (it->path.size() > path.size())
{
// prendre en compte l'éventuel "/" final si location est un dossier
if (it->path.size()-1 > path.size() || it->path[it->path.size()-1] != '/')
{
++it;
continue;
}
}
if (path.compare(0, it->path.size(), it->path) == 0)
{
if (it->path.size() == path.size())
break;
else if (path[it->path.size()-1] == '/')
break;
}
++it;
}
if (it != server.locations.end())
return (&(*it));
else
return (&(server.locations.back()));
}
// Temporary Global Scope. Probably move to Client in the future. // Temporary Global Scope. Probably move to Client in the future.
const LocationConfig *_determine_location(const ServerConfig &server, const std::string &path) const LocationConfig *_determine_location(const ServerConfig &server, const std::string &path)
{ {
std::cout << "determin location path sent: " << path << '\n'; std::cout << "determin location path sent: " << path << '\n';
/// NO FUCKING IDEA WHY BUT...
// basically if 2 strings are identical to a point, compare from
// longer one or it'll freak out cuz of \0 or something idk
//// Basically: str.compare() from the larger string...
/* RULES *** /* RULES ***
If a path coresponds exactly to a location, use that one If a path coresponds exactly to a location, use that one
@@ -237,105 +181,39 @@ if no path coresponds then use the most correct one
most correct means the most precise branch that is still above most correct means the most precise branch that is still above
the point we are aiming for the point we are aiming for
New Rule for location paths, they never end in /
Sooo
If we get a url that ends in / ignore the last /
*/ */
// IS THERE A WAY TO SIMPLIFY THIS LOGIC ??? std::string uri = path;
if (uri[uri.size() - 1] == '/')
// what if i tack on a / at the end of path if there isn't one uri.erase(uri.size() - 1);
// and then compare it to things that are their normal length?
std::string tmp = path;
if (tmp[tmp.size() - 1] != '/')
tmp.push_back('/');
/test/index.html/
/test/index.html
for (std::vector<LocationConfig>::const_iterator it = server.locations.begin(); it != server.locations.end(); it++) for (std::vector<LocationConfig>::const_iterator it = server.locations.begin(); it != server.locations.end(); it++)
{ {
std::cout << it->path << " -- "; std::cout << it->path << " -- ";
if (it->path.size() > tmp.size()) if (it->path.size() > uri.size())
continue ;
if (tmp.compare(0, it->path.size(), it->path) == 0)
{
std::cout << "checking with last /\n";
if (it->path.size() == tmp.size())
{
std::cout << "path sizes are equal \n";
return (&(*it));
}
else if (tmp[it->path.size() - 1] == '/')
{
std::cout << "ends in /\n";
return (&(*it));
}
}
/*
// 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"; std::cout << "skipping this one\n";
continue ; continue ;
} }
if (uri.compare(0, it->path.size(), it->path) == 0)
// if (it->path[it->path.size() - 1] == '/')
if (path[path.size() - 1] == '/')
{ {
if (path.compare(0, it->path.size(), it->path) == 0) if (it->path.size() == uri.size())
{
std::cout << "checking with last /\n";
if (it->path.size() == path.size())
{
std::cout << "path sizes are equal \n";
return (&(*it)); return (&(*it));
} else if (uri[it->path.size()] == '/')
else if (path[it->path.size() - 1] == '/')
{
std::cout << "ends in /\n";
return (&(*it)); 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));
}
}
}
*/
}
// if (it != server.locations.end())
// return (&(*it));
// else
return (&(server.locations.back())); return (&(server.locations.back()));
// /test/mdr // /test/mdr
// /test/mdr/ // /test/mdr/
// /test/mdrBST // /test/mdrBST
@@ -349,17 +227,16 @@ if no path coresponds then use the most correct one
/test/test_deepei /test/test_deepei
/test/test_deepei/ /test/test_deepei/
/test/test_deeperi /test/test_deeperi
/test/test_deeper/super_deep/
/test/aaaaaaaaaaa/super_deep/
*/ */
} }
std::string Webserv::_determine_file_extension(const std::string &path) const std::string Webserv::_determine_file_extension(const std::string &path) const
{ {
size_t dot_pos = path.rfind("."); size_t dot_pos = path.rfind(".");