Well we learned a lot from Nginx, starting to incorporate some, but hoping for feedback before i do most of that, instead worked on improving the location sorter and checking that locations paths are valid, close but not quite done

This commit is contained in:
Me
2022-08-05 03:42:42 +02:00
parent f7e6b61811
commit 9ac14aa1aa
5 changed files with 90 additions and 53 deletions

View File

@@ -10,8 +10,9 @@ server {
# client_body_limit 400;
index index.html; # this is another comment
# i think root requires leading /
# root goop;
root www;
root /www;
# root www/test; # also works
# root /www; # stat does not like this kind of definition
# root /usr; # because it's looking at / aka absolute path
@@ -19,21 +20,27 @@ server {
# root /home/me/Programming/42/group_webserv; # but this is fine
location /test {
root www/test;
root /www/test;
index index.html;
}
# If not explicitly set, ConfigParser need to genererate a location block
# like this for path "/" (based on field "root" and "index" of the server)
location / {
root www;
root /www;
index index.html;
allow_methods DELETE;
}
allow_methods GET POST;
location /test/something.html {
allow_methods GET POST DELETE;
}
location /something/long/here {
# location /something/long/here {
# }
location /something/long {
}
location /something/long/here/but/more {

View File

@@ -17,6 +17,10 @@
# include <vector>
# include <string>
# include <iostream>
# include <sys/stat.h> // stat()
# include <stdio.h> // printf(), gotta go
# include "utils.hpp"
@@ -99,6 +103,38 @@ 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)
{
std::cout << "locations are equal\n";
std::string tmp_path_lhs = root + path;
std::cout << "root + path: " << tmp_path_lhs << '\n';
// const char *c_path_lhs = (root + path).substr(1).c_str();
// could the problem be that i'm in the .hpp ?
const char *c_path_lhs = tmp_path_lhs.substr(1).c_str();
const char *c_path_rhs = (rhs.root + rhs.path).substr(1).c_str();
printf("lhs path: %s\n", c_path_lhs);
printf("rhs path: %s\n", c_path_rhs);
struct stat sl;
struct stat sr;
if (stat(c_path_lhs, &sl) == 0 && S_ISREG(sl.st_mode))
{
std::cout << "lhs is a file\n";
--comp_lhs;
}
if (stat(c_path_rhs, &sr) == 0 && S_ISREG(sr.st_mode))
{
std::cout << "rhs is a file\n";
--comp_rhs;
}
// do i need to free c_path's ???
}
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 <

View File

@@ -146,7 +146,12 @@ LocationConfig ConfigParser::_parse_location(size_t *start)
ret.client_body_limit = 0;
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 /");
// in theory now curr should be right after the "path"
curr = _content.find_first_not_of(" \t\n", curr);
@@ -178,6 +183,9 @@ LocationConfig ConfigParser::_parse_location(size_t *start)
}
#include <stdio.h>
void ConfigParser::_set_server_values(ServerConfig *server, \
const std::string key, std::string value)
{
@@ -232,22 +240,33 @@ void ConfigParser::_set_server_values(ServerConfig *server, \
}
else if (key == "root" && size == 1 && server->root == "")
{
// consider using lstat if you don't? want symlinks included?
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].c_str();
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";
server->root = tmp_val[0];
}
else
throw std::invalid_argument("root dir could not be opened");
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);
@@ -350,7 +369,10 @@ void ConfigParser::_set_location_values(LocationConfig *location, \
throw std::invalid_argument("missing value");
else if (key == "root" && size == 1 && location->root == "")
{
const char* folder = tmp_val[0].c_str();
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))

View File

@@ -3,47 +3,6 @@
#include "ConfigParser.hpp"
// technically doesn't belong to ConfigParser or any other class
// adding static in front doesn't work...
/*
bool compareLocationConfigs(const LocationConfig &a, const LocationConfig &b)
{
int len_a;
int len_b;
size_t tmp = 0;
// consider adding 1 to path that ends in a file not folder.
while ((tmp = a.path.find_first_of("/", tmp)) != std::string::npos)
++len_a;
tmp = 0;
while ((tmp = b.path.find_first_of("/", tmp)) != std::string::npos)
++len_b;
return (len_a < len_b); // right comparison ? not <= ?
}
*/
/*
class spec_int
{
public:
spec_int() {}
spec_int(int i): i(i){}
~spec_int() {}
// spec_int(int start, int num)
// {
// }
int i;
bool operator<(const spec_int &a, const spec_int &b)
{
return (a.i < b.i);
}
}
*/
void ConfigParser::_post_processing(std::vector<ServerConfig> *servers)
{
@@ -83,7 +42,7 @@ void ConfigParser::_post_processing(std::vector<ServerConfig> *servers)
// actually do this at the end, once we know if there aren't any locations
// with path /
/* if (!_find_root_path_location(it->locations))
if (!_find_root_path_location(it->locations))
{
LocationConfig tmp;
@@ -95,7 +54,7 @@ void ConfigParser::_post_processing(std::vector<ServerConfig> *servers)
tmp.redirect_status = 0;
it->locations.push_back(tmp);
}
*/
std::vector<LocationConfig>::iterator it_l = it->locations.begin();
// first check locations we have
@@ -103,9 +62,11 @@ void ConfigParser::_post_processing(std::vector<ServerConfig> *servers)
{
// 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.c_str();
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";
@@ -114,7 +75,7 @@ void ConfigParser::_post_processing(std::vector<ServerConfig> *servers)
}
else
throw std::invalid_argument("location dir could not be opened");
*/

11
www/test/something.html Normal file
View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>Le Webserv in test and is Something</title>
</head>
<body>
<h1 style="text-align:center">Le index (˘ ͜ʖ˘)</h1>
<hr>
<p style="text-align:center">(˚3˚)</p>
</body>
</html>