Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parser #14

Merged
merged 5 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions arquivo.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
server {
server_name server.com;
listen 127.0.0.1:4242;
error_page 403 error_pages/403.html;
error_page 404 error_pages/404.html;
error_page 405 error_pages/405.html;
error_page 413 error_pages/413.html;
error_page 500 error_pages/500.html;
client_max_body_size 100000;

location / {
autoindex on;
allow_methods GET POST DELETE;
root web_root;
upload_dir web_root/uploads
index index.html index.php;
cgi .php cgi-bin/php-cgi;
}

location /potato/ {
autoindex on;
root web_root;
allow_methods GET POST DELETE;
}

location /redirect/ {
return 301 https://google.com;
}

}
server {
server_name server2.com;
listen 127.0.0.1:4242;
error_page 403 error_pages/403.html;
error_page 404 error_pages/404.html;
error_page 405 error_pages/405.html;
error_page 413 error_pages/413.html;
error_page 500 error_pages/500.html;
client_max_body_size 100;

location / {
autoindex off;
allow_methods GET POST;
root web_root;
upload_dir web_root/uploads
index index.html index.php;
cgi .php cgi-bin/php-cgi;
}

location /potato2/ {
autoindex on;
root web_root;
allow_methods GET;
}

location /redirect/ {
return 301 https://google.com;
}

}
42 changes: 42 additions & 0 deletions include/Config.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef CONFIG_HPP
#define CONFIG_HPP

#include "common.hpp"

struct LocationConfig {
std::string path;
bool autoindex;
std::vector<std::string> allow_methods;
std::string root;
std::string upload_dir;
std::vector<std::string> index;
std::string cgi_extension;
std::string cgi_path;
std::string redirect;
};

struct ServerConfig {
std::string server_name;
std::string listen;
std::map<int, std::string> error_pages;
size_t client_max_body_size;
std::vector<LocationConfig> locations;
};

class Config {
public:
Config(const std::string &filePath);
const std::vector<ServerConfig>& getServers() const;
void printServers() const;

private:
std::string filePath;
std::vector<ServerConfig> servers;

void parseConfigFile();
void parseServerBlock(const std::vector<std::string> &lines, size_t &index);
void parseLocationBlock(const std::vector<std::string> &lines, size_t &index, ServerConfig &server);
std::string trim(const std::string& str);
};

#endif
147 changes: 147 additions & 0 deletions src/Config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
#include "Config.hpp"

Config::Config(const std::string& filePath) : filePath(filePath) {
parseConfigFile();
}

void Config::parseConfigFile() {
std::ifstream configFile(filePath.c_str());
if (!configFile.is_open()) {
std::cerr << "Error opening config file: " << filePath << std::endl;
return;
}

std::string line;
std::vector<std::string> lines;
while (std::getline(configFile, line))
lines.push_back(line);
size_t index = 0;
while (index < lines.size()) {
std::string trimmedLine = trim(lines[index]);
if (trimmedLine == "server {")
parseServerBlock(lines, index);
++index;
}
}

void Config::parseServerBlock(const std::vector<std::string>& lines, size_t& index) {
ServerConfig server;

while (++index < lines.size()) {
std::string trimmedLine = trim(lines[index]);
if (trimmedLine == "}")
break;
else if (trimmedLine.find("server_name") == 0)
server.server_name = trimmedLine.substr(12);
else if (trimmedLine.find("listen") == 0) {
std::istringstream iss(trimmedLine.substr(7));
iss >> server.listen;
}
else if (trimmedLine.find("client_max_body_size") == 0) {
std::istringstream iss(trimmedLine.substr(21));
iss >> server.client_max_body_size;
}
else if (trimmedLine.find("error_page") == 0) {
size_t pos = trimmedLine.find(' ', 11);
int errorCode;
std::istringstream iss(trimmedLine.substr(11, pos - 11));
iss >> errorCode;
std::string errorPage = trimmedLine.substr(pos + 1);
server.error_pages[errorCode] = errorPage;
}
else if (trimmedLine.find("location") == 0)
parseLocationBlock(lines, index, server);
}

servers.push_back(server);
}


void Config::parseLocationBlock(const std::vector<std::string>& lines, size_t& index, ServerConfig& server) {
LocationConfig location;

size_t pos = lines[index].find(' ');
location.path = lines[index].substr(pos + 1);

while (++index < lines.size()) {
std::string trimmedLine = trim(lines[index]);
if (trimmedLine == "}")
break;
else if (trimmedLine.find("autoindex") == 0)
location.autoindex = (trimmedLine.substr(10) == "on");
else if (trimmedLine.find("root") == 0)
location.root = trimmedLine.substr(5);
else if (trimmedLine.find("upload_dir") == 0)
location.upload_dir = trimmedLine.substr(11);
else if (trimmedLine.find("index") == 0) {
std::istringstream iss(trimmedLine.substr(6));
std::string idx;
while (iss >> idx)
location.index.push_back(idx);
}
else if (trimmedLine.find("allow_methods") == 0) {
std::istringstream iss(trimmedLine.substr(14));
std::string method;
while (iss >> method)
location.allow_methods.push_back(method);
}
else if (trimmedLine.find("cgi_extension") == 0)
location.cgi_extension = trimmedLine.substr(14);
else if (trimmedLine.find("cgi_path") == 0)
location.cgi_path = trimmedLine.substr(9);
else if (trimmedLine.find("redirect") == 0)
location.redirect = trimmedLine.substr(9);
}

server.locations.push_back(location);
}

std::string Config::trim(const std::string& str) {
size_t first = 0;
size_t last = str.size() - 1;

while (first <= last && std::isspace(str[first]))
++first;
while (last >= first && std::isspace(str[last]))
--last;
if (first > last)
return "";
return str.substr(first, last - first + 1);
}

void Config::printServers() const {
std::cout << "Number of servers: " << servers.size() << "\n\n";
for (size_t i = 0; i < servers.size(); ++i) {
const ServerConfig& server = servers[i];
std::cout << "Server Name: " << server.server_name << "\n";
std::cout << "Listen: " << server.listen << "\n";
std::cout << "Client Max Body Size: " << server.client_max_body_size << "\n";

for (std::map<int, std::string>::const_iterator it = server.error_pages.begin(); it != server.error_pages.end(); ++it) {
std::cout << "Error Page " << it->first << ": " << it->second << "\n";
}

for (size_t j = 0; j < server.locations.size(); ++j) {
const LocationConfig& location = server.locations[j];
std::cout << "Location: " << location.path << "\n";
std::cout << " Autoindex: " << (location.autoindex ? "on" : "off") << "\n";
std::cout << " Root: " << location.root << "\n";
std::cout << " Upload Dir: " << location.upload_dir << "\n";
std::cout << " Index: ";
for (size_t k = 0; k < location.index.size(); ++k)
std::cout << location.index[k] << " ";
std::cout << "\n";
std::cout << " Allow Methods: ";
for (size_t k = 0; k < location.allow_methods.size(); ++k)
std::cout << location.allow_methods[k] << " ";
std::cout << "\n";
if (!location.cgi_extension.empty()) {
std::cout << " CGI Extension: " << location.cgi_extension << "\n";
std::cout << " CGI Path: " << location.cgi_path << "\n";
}
if (!location.redirect.empty())
std::cout << " Redirect: " << location.redirect << "\n";
}
std::cout << "\n";
}
}
18 changes: 11 additions & 7 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

int main(void)
{
try {
Server server("127.0.0.1", PORT);
server.run();
} catch (std::exception &e) {
std::cerr << RED("Error: ") << e.what() << std::endl;
}
return 0;
Config config("arquivo.conf");
config.printServers();


// try {
// Server server("127.0.0.1", PORT);
// server.run();
// } catch (std::exception &e) {
// std::cerr << RED("Error: ") << e.what() << std::endl;
// }
// return 0;
}