added multipart upload file,
it works, but need some adjustements, refactoring and testing
This commit is contained in:
@@ -97,7 +97,7 @@ class Webserv
|
||||
void _autoindex(Client *client, const std::string &path);
|
||||
// method_post.cpp
|
||||
void _post(Client *client, const std::string &path);
|
||||
void _post_file(Client *client, const std::string &path);
|
||||
void _upload_files(Client *client);
|
||||
// method_delete.cpp
|
||||
void _delete(Client *client, const std::string &path);
|
||||
void _delete_file(Client *client, const std::string &path);
|
||||
|
||||
@@ -112,9 +112,11 @@ void Webserv::_init_http_status_map()
|
||||
_http_status.insert(status_pair(405, S405));
|
||||
_http_status.insert(status_pair(408, S408));
|
||||
_http_status.insert(status_pair(413, S413));
|
||||
_http_status.insert(status_pair(415, S415));
|
||||
|
||||
_http_status.insert(status_pair(500, S500));
|
||||
_http_status.insert(status_pair(501, S501));
|
||||
_http_status.insert(status_pair(505, S505));
|
||||
}
|
||||
|
||||
void Webserv::_init_mime_types_map()
|
||||
|
||||
@@ -8,51 +8,119 @@ void Webserv::_post(Client *client, const std::string &path)
|
||||
WIP
|
||||
https://www.rfc-editor.org/rfc/rfc9110.html#name-post
|
||||
*/
|
||||
_post_file(client, path);
|
||||
(void)path;
|
||||
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_file(client);
|
||||
}
|
||||
|
||||
void Webserv::_post_file(Client *client, const std::string &path)
|
||||
#define DEFAULT_NAME "unnamed_file"
|
||||
// TODO : Loop for multi body
|
||||
void Webserv::_upload_files(Client *client)
|
||||
{
|
||||
std::ofstream ofd;
|
||||
|
||||
std::vector<MultipartBody>::const_iterator body_it = client->get_rq_multi_bodys().begin();
|
||||
std::string path;
|
||||
std::string filename;
|
||||
size_t pos;
|
||||
bool file_existed;
|
||||
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 ?
|
||||
if (file_existed && access(path.c_str(), W_OK) == -1)
|
||||
while (body_it != client->get_rq_multi_bodys().end())
|
||||
{
|
||||
std::perror("err access()");
|
||||
client->status = 403;
|
||||
return ;
|
||||
}
|
||||
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);
|
||||
|
||||
ofd.open(path.c_str(), std::ios::trunc);
|
||||
if (!ofd)
|
||||
{
|
||||
std::cerr << path << ": ofd.open fail" << '\n';
|
||||
client->status = 500;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Content-Length useless at this point ?
|
||||
ofd << client->get_rq_body();
|
||||
|
||||
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;
|
||||
}
|
||||
else if (file_existed)
|
||||
{
|
||||
client->status = 200;
|
||||
// WIP https://www.rfc-editor.org/rfc/rfc9110.html#name-200-ok
|
||||
}
|
||||
else
|
||||
{
|
||||
client->status = 201;
|
||||
// WIP https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.3-4
|
||||
}
|
||||
++body_it;
|
||||
ofd.close();
|
||||
}
|
||||
|
||||
if (file_existed) // with multi body it doesn't make much sense
|
||||
{
|
||||
// client->status = 200;
|
||||
client->status = 204; // DEBUG 204
|
||||
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->status = 204; // DEBUG 204
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ void Webserv::_request(Client *client)
|
||||
}
|
||||
else if (ret == READ_COMPLETE)
|
||||
{
|
||||
if (client->body_complete)
|
||||
if (client->body_complete && client->get_rq_multi_bodys().empty()) // DEBUG
|
||||
std::cerr << "______BODY\n" << client->get_rq_body() << "\n______\n"; // DEBUG
|
||||
_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_MOD);
|
||||
client->request_complete = true;
|
||||
|
||||
@@ -21,7 +21,10 @@ void Webserv::_response(Client *client)
|
||||
}
|
||||
else if (ret == SEND_COMPLETE)
|
||||
{
|
||||
if (client->get_rq_headers("Connection") == "close" || client->status == 408)
|
||||
if (client->get_rq_headers("Connection") == "close"
|
||||
|| client->status == 400 // TODO: Refactoring
|
||||
|| client->status == 408
|
||||
|| client->status == 413)
|
||||
_close_client(client->get_cl_fd());
|
||||
else
|
||||
{
|
||||
@@ -61,7 +64,10 @@ void Webserv::_append_base_headers(Client *client)
|
||||
{
|
||||
client->response.append("Server: Webserv/0.1" CRLF);
|
||||
|
||||
if (client->get_rq_headers("Connection") == "close")
|
||||
if (client->get_rq_headers("Connection") == "close"
|
||||
|| client->status == 400 // TODO: Refactoring
|
||||
|| client->status == 408
|
||||
|| client->status == 413)
|
||||
client->response.append("Connection: close" CRLF);
|
||||
else
|
||||
client->response.append("Connection: keep-alive" CRLF);
|
||||
|
||||
@@ -12,7 +12,12 @@ void Webserv::_timeout()
|
||||
std::cerr << "timeout request fd " << it->get_cl_fd() << "\n";
|
||||
it->status = 408;
|
||||
_epoll_update(it->get_cl_fd(), EPOLLOUT, EPOLL_CTL_MOD);
|
||||
|
||||
// DEBUG, close without repsonse 408
|
||||
/* _close_client(it->get_cl_fd());
|
||||
it = _clients.begin(); */
|
||||
}
|
||||
// else // DEBUG
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user