#include "Webserv.hpp" std::string Webserv::_replace_url_root(Client *client, std::string path) { std::cerr << "assigned_location->path = " << client->assigned_location->path << "\n"; // debug std::cerr << "path before = " << path << "\n"; // DEBUG if (client->assigned_location->path == "/") path.insert(0, client->assigned_location->root); else path.replace(0, client->assigned_location->path.size(), client->assigned_location->root); std::cerr << "path after = " << path << "\n"; // DEBUG return path; } // const? void Webserv::_get(Client *client, std::string &path) { /* https://www.rfc-editor.org/rfc/rfc9110.html#name-get */ 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); return ; } } if (client->assigned_location->autoindex == true) _autoindex(client, path); else client->status = 404; } else _get_file(client, path); } # define MAX_FILESIZE 1 * MB // unused void Webserv::_get_file(Client *client, const std::string &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. */ 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 ; } */ // const? void Webserv::_autoindex(Client *client, const std::string &path) { std::cout << "_autoindex()\n"; // std::cout << "client target: " << client->get_rq_target() << '\n'; std::string dir_list; DIR *dir; struct dirent *ent; // std::cout << "location root: " << client->assigned_location->root << " location path: " << client->assigned_location->path << '\n'; // std::cout << "Path in auto is: " << path << '\n'; 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); /* print all the files and directories within directory */ while ((ent = readdir (dir)) != NULL) { // std::cout << "ent: " << ent->d_name << '\n'; if (strcmp(".", ent->d_name) == 0) continue ; dir_list.append("get_rq_target()); dir_list.append(client->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); dir_list.append(""); dir_list.append("\r\n"); // is this right? } // nginx.org.
// index1.html // apparently this is more than good enough! // .. dir_list.append(AUTOINDEX_END); // std::cout << "\n\n" << dir_list << '\n'; closedir (dir); _append_body(client, dir_list, "html"); } else { // in theory not possible cuz we already checked... std::cerr << "could not open dir\n"; // throw? return ; } }