#include "Webserv.hpp" 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); 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. 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 // std::string script_output; if (_is_cgi(client)) { script_output = _exec_cgi(client); // DEBUG std::cout << "\n____script_output____\n" << script_output << "\n_______________\n"; // wip check output of script _check_script_output(client, script_output); client->response += script_output; return; } // // END TMP HUGO _get_file(client, path); } # define MAX_FILESIZE 1000000 // (1Mo) 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 << "made it to get_file\n"; if (access(path.c_str(), F_OK) == -1) { std::perror("err access()"); client->status = 404; return ; } if (access(path.c_str(), R_OK) == -1) { std::perror("err access()"); client->status = 403; return ; } ifd.open(path.c_str(), std::ios::ate); if (!ifd) { std::cerr << path << ": ifd.open fail" << '\n'; client->status = 500; } else { std::streampos size = ifd.tellg(); // WIP : Chunk or not chunk (if filesize too big) if (size > MAX_FILESIZE) { // Then chunk client->status = 500; // WIP temp std::cerr << "File too large for non chunk body\n"; return ; } ifd.seekg(0, std::ios::beg); 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); } } } // i only sort of need &path... // def can improve but works for now... //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"; (void)path; std::string dir_list; DIR *dir; struct dirent *ent; // 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) { /* print all the files and directories within directory */ dir_list.append(AUTOINDEX_START); dir_list.append(client->assigned_location->path); dir_list.append(AUTOINDEX_MID1); dir_list.append(client->assigned_location->path); dir_list.append(AUTOINDEX_MID2); while ((ent = readdir (dir)) != NULL) { if (strcmp(".", ent->d_name) == 0) continue ; dir_list.append("assigned_location->path.c_str()); 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... /* could not open directory */ // perror (""); std::cout << "could not open dir\n"; return ; } }