#include "Webserv.hpp" #define MAX_FILESIZE 1 * MB // unused /* https://www.rfc-editor.org/rfc/rfc9110.html#name-get */ void Webserv::_get(Client *client, std::string &path) { std::cout << "_get()\n"; if (eval_file_type(path) == IS_DIR) { if (path[path.size() - 1] != '/') path.push_back('/'); for (size_t i = 0; i < client->assigned_location->index.size(); i++) { if (eval_file_type(path + client->assigned_location->index[i]) == IS_FILE) { path.append(client->assigned_location->index[i]); _get_file(client, path); std::cerr << "Added an index\n"; //debug return ; } } if (client->assigned_location->autoindex == true) _autoindex(client, path); else client->status = 404; } else _get_file(client, path); } /* std::ios::binary https://gcc.gnu.org/onlinedocs/libstdc++/manual/fstreams.html#std.io.filestreams.binary tldr : its seems to not be so simple to do read/write of binary file in a portable way. */ 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() ? std::stringstream buf; std::cout << "_get_file()\n"; client->status = ::eval_file_access(path, R_OK); if (client->status) return; ifd.open(path.c_str()); if (!ifd) { std::cerr << path << ": ifd.open fail" << '\n'; client->status = 500; } else { buf << ifd.rdbuf(); if (!ifd || !buf) { std::cerr << path << ": ifd.read fail" << '\n'; client->status = 500; } else { client->status = 200; std::string file_ext = _determine_file_extension(path); _append_body(client, buf.str(), file_ext); } } } /* // WIP Low priority : Chunk or not chunk (if filesize > MAX_FILESIZE) // WITH flag "std::ios::ate" for open() std::streampos size = ifd.tellg(); ifd.seekg(0, std::ios::beg); if (size > MAX_FILESIZE) { // Chunked GET here return ; } */ /* nginx.org.
index1.html .. */ void Webserv::_autoindex(Client *client, const std::string &path) { std::cout << "_autoindex()\n"; std::string dir_list; DIR *dir; struct dirent *ent; if ( (dir = opendir(path.c_str()) ) != NULL) { dir_list.append(AUTOINDEX_START); dir_list.append(path); dir_list.append(AUTOINDEX_MID1); dir_list.append(path); dir_list.append(AUTOINDEX_MID2); while ((ent = readdir (dir)) != NULL) { if (strcmp(".", ent->d_name) == 0) continue ; dir_list.append("get_rq_abs_path()); if (dir_list[dir_list.size() - 1] != '/') dir_list.push_back('/'); dir_list.append(ent->d_name); dir_list.append("\">"); dir_list.append(ent->d_name); if (ent->d_type == DT_DIR) dir_list.append("/"); dir_list.append(""); dir_list.append("\n"); } dir_list.append(AUTOINDEX_END); closedir (dir); client->status = 200; _append_body(client, dir_list, "html"); } else { client->status = 500; perror("could not open dir"); return ; } } std::string Webserv::_determine_file_extension(const std::string &path) const { size_t dot_pos = path.rfind("."); if (dot_pos != NPOS && dot_pos + 1 < path.size()) return ( path.substr(dot_pos + 1) ); return (std::string("")); }