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 {
index index1.html subdex.html;
root ./www/test/;
}
location /test/index1.html {
root ./www/test/;
index index1.html subdex.html;
}
@@ -38,19 +40,22 @@ server {
location /stylesheet/ {
# root ./www/../;
root ./;
root ./styelsheet/;
}
location /test/something.html {
# allow_methods DELETE;
root ./www/test/;
}
location /test/test_deeper/ {
# allow_methods
autoindex on;
root ./www/test/test_deeper/;
}
location /test/test_deeper/super_deep {
root ./www/test/test_deeper/super_deep/;
autoindex on;
}

View File

@@ -1,11 +1,8 @@
IN 42 SUBJECT AND/OR PRIORITY :
- Fix "href" in autoindex
- CGI
- chunked request (response not mandatory it seems)
- fix need for index and autoindex config
- 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)
- upload files with config "upload_dir"
- _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"
@@ -232,9 +221,9 @@ void ConfigParser::_set_server_values(ServerConfig *server, \
else if (key == "root" && size == 1 && server->root == "")
{
// remove trailing /
if (tmp_val[0][tmp_val[0].size() - 1] != '/')
tmp_val[0].push_back('/');
// tmp_val[0].erase(tmp_val[0].size() - 1, 1);
if (tmp_val[0][tmp_val[0].size() - 1] == '/')
tmp_val[0].erase(tmp_val[0].size() - 1, 1);
// tmp_val[0].push_back('/');
server->root = tmp_val[0];
}
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");
else if (key == "root" && size == 1 && location->root == "")
{
// add trailing /
if (tmp_val[0][tmp_val[0].size() - 1] != '/')
tmp_val[0].push_back('/');
// tmp_val[0].erase(tmp_val[0].size() - 1, 1);
// remove trailing /
if (tmp_val[0][tmp_val[0].size() - 1] == '/')
tmp_val[0].erase(tmp_val[0].size() - 1, 1);
// tmp_val[0].push_back('/');
location->root = tmp_val[0];
}
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)
it_l->allow_methods = ANY_METHODS;
// also
if (it_l->index.empty() && it_l->autoindex == false)
it_l->index = it->index;
// nothing to be done for cgi_ext, error_pages, redirect
if (path_is_valid(it_l->root + it_l->path) == 1 \
&& it_l->path[it_l->path.size() - 1] != '/')
it_l->path.push_back('/');
// if (path_is_valid(it_l->root) == IS_DIR
// && it_l->path[it_l->path.size() - 1] != '/')
// 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;
}

View File

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

View File

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

View File

@@ -2,8 +2,6 @@
#ifndef 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 \
"<!DOCTYPE html>"\
"<html>"\

View File

@@ -1,68 +1,16 @@
#include "Webserv.hpp"
// TODO : path_is_valid() Macro for return value
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();
// this might not be the best thing, a voir
// path.insert(0, client->assigned_location->root);
//client->assigned_location->path
std::cerr << "path before = " << path << "\n"; // DEBUG
path.replace(0, client->assigned_location->path.size(), client->assigned_location->root);
std::cerr << "path after = " << path << "\n"; // DEBUG
std::cerr << "path = " << path << "\n";
// 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
// TMP HUGO ( We move this in process_switch() )
//
std::string script_output;
if (_is_cgi(client))
@@ -78,7 +26,28 @@ Where does cgi fit in in all this ???
//
// END TMP HUGO
_get_file(client, path);
// 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);
return ;
}
}
if (client->assigned_location->autoindex == true)
_autoindex(client, path);
}
else
_get_file(client, path);
}
# 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, std::string &path)
{
// std::cout << "made it to _autoindex\n";
std::cout << "made it to _autoindex\n";
(void)path;
std::string dir_list;
DIR *dir;
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: "
// << client->assigned_location->path << '\n';
// if ((dir = opendir (path.c_str())) != NULL)
if ((dir = opendir ((client->assigned_location->root + client->assigned_location->path).c_str())) != NULL)
std::cout << "Path in auto is: " << path << '\n';
if ( (dir = opendir(path.c_str()) ) != NULL)
{
/* print all the files and directories within directory */
dir_list.append(AUTOINDEX_START);
dir_list.append(client->assigned_location->path);
dir_list.append(path);
dir_list.append(AUTOINDEX_MID1);
dir_list.append(client->assigned_location->path);
dir_list.append(path);
dir_list.append(AUTOINDEX_MID2);
while ((ent = readdir (dir)) != NULL)
{
if (strcmp(".", ent->d_name) == 0)
continue ;
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("\">");
dir_list.append(ent->d_name);

View File

@@ -169,67 +169,11 @@ ServerConfig *_determine_process_server(Client *client, std::vector<ServerConfig
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.
const LocationConfig *_determine_location(const ServerConfig &server, const std::string &path)
{
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 ***
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
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 ???
// what if i tack on a / at the end of path if there isn't one
// 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
std::string uri = path;
if (uri[uri.size() - 1] == '/')
uri.erase(uri.size() - 1);
for (std::vector<LocationConfig>::const_iterator it = server.locations.begin(); it != server.locations.end(); it++)
{
std::cout << it->path << " -- ";
if (it->path.size() > tmp.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())
if (it->path.size() > uri.size())
{
std::cout << "skipping this one\n";
continue ;
}
// if (it->path[it->path.size() - 1] == '/')
if (path[path.size() - 1] == '/')
if (uri.compare(0, it->path.size(), it->path) == 0)
{
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));
}
}
if (it->path.size() == uri.size())
return (&(*it));
else if (uri[it->path.size()] == '/')
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/mdrBST
@@ -349,17 +227,16 @@ if no path coresponds then use the most correct one
/test/test_deepei
/test/test_deepei/
/test/test_deeperi
/test/test_deeper/super_deep/
/test/aaaaaaaaaaa/super_deep/
*/
}
std::string Webserv::_determine_file_extension(const std::string &path) const
{
size_t dot_pos = path.rfind(".");