#include "Webserv.hpp" void Webserv::_post(Client *client, const std::string &path) { /* https://www.rfc-editor.org/rfc/rfc9110.html#name-post */ (void)path; // unused, we use "assigned_location->upload_dir" instead std::cout << "_post()\n"; std::cerr << "upload_dir = " << client->assigned_location->upload_dir << "\n"; if (client->get_rq_abs_path() != client->assigned_location->path) client->status = 404; // 404 ? J'ai un doute. else if (client->assigned_location->upload_dir.empty()) client->status = 404; // 404 ? J'ai un doute. else if (client->get_rq_multi_bodys().empty()) { client->status = 415; client->response.append("Accept: multipart/form-data"); // empty, no encoding accepted client->response.append(CRLF); } else _upload_files(client); } #define DEFAULT_NAME "unnamed_file" // TODO : Loop for multi body void Webserv::_upload_files(Client *client) { std::cout << "_upload_files()\n"; std::ofstream ofd; std::vector::const_iterator body_it = client->get_rq_multi_bodys().begin(); std::string path; std::string filename; size_t pos; bool file_existed = false; client->status = ::eval_file_mode(client->assigned_location->upload_dir, W_OK); if (client->status) return; while (body_it != client->get_rq_multi_bodys().end()) { if (body_it->body.empty()) { ++body_it; continue; } // Content-Disposition: form-data; name="upload_file"; filename="camion.jpg" ::print_map(body_it->headers); filename = client->get_rq_multi_bodys_headers("Content-Disposition", body_it); std::cerr << "filename ="<< filename << "\n"; pos = filename.find("filename="); if (pos != NPOS) { filename = filename.substr(pos + sizeof("filename=")-1); std::cerr << "filename ="<< filename << "\n"; // A l'arrache pour enlever les " filename.erase(0, 1); std::cerr << "filename ="<< filename << "\n"; filename.erase(filename.size()-1, 1); std::cerr << "filename ="<< filename << "\n"; std::cerr << "filename ="<< filename << "\n"; if (filename.empty()) filename = DEFAULT_NAME; } else { filename = DEFAULT_NAME; } std::cerr << "filename ="<< filename << "\n"; path = client->assigned_location->upload_dir; // Assume there a final '/' path.append(filename); if (::access(path.c_str(), F_OK) == -1) file_existed = false; else file_existed = true; // How to determine status 403 for file that dont already exist ? access() on the upload_dir ? if (file_existed && ::access(path.c_str(), W_OK) == -1) { std::perror("err access()"); client->status = 403; return ; } ofd.open(path.c_str(), std::ios::trunc); if (!ofd) { std::cerr << path << ": ofd.open fail" << '\n'; client->status = 500; return; } ofd << body_it->body; if (!ofd) { std::cerr << path << ": ofd.write fail" << '\n'; client->status = 500; return; } ++body_it; ofd.close(); } client->status = 204; client->response.append(CRLF); // https://www.rfc-editor.org/rfc/rfc9110.html#name-204-no-content } /* if (file_existed) // with multi body it doesn't make much sense { client->status = 200; client->response.append("Location: "); client->response.append("/index.html"); // WIP client->response.append(CRLF); client->response.append(CRLF); // WIP https://www.rfc-editor.org/rfc/rfc9110.html#name-200-ok } else { client->status = 201; client->response.append("Location: "); client->response.append("/index.html"); // WIP client->response.append(CRLF); client->response.append(CRLF); // WIP https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.3-4 } */