Multiples minors changes (cgi env, comment, ...)
This commit is contained in:
107
srcs/Client.cpp
107
srcs/Client.cpp
@@ -75,10 +75,12 @@ Client & Client::operator=( Client const & rhs )
|
|||||||
* PUBLIC MEMBER FUNCTIONS
|
* PUBLIC MEMBER FUNCTIONS
|
||||||
*********************************************/
|
*********************************************/
|
||||||
|
|
||||||
// http headers :
|
/* HTTP Headers :
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
|
https://www.iana.org/assignments/http-fields/http-fields.xhtml
|
||||||
// https://www.ibm.com/docs/en/cics-ts/5.3?topic=protocol-http-requests
|
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
|
||||||
// https://www.tutorialspoint.com/http/http_requests.htm
|
https://www.ibm.com/docs/en/cics-ts/5.3?topic=protocol-http-requests
|
||||||
|
https://www.tutorialspoint.com/http/http_requests.htm
|
||||||
|
*/
|
||||||
void Client::parse_request_headers(std::vector<ServerConfig> &servers)
|
void Client::parse_request_headers(std::vector<ServerConfig> &servers)
|
||||||
{
|
{
|
||||||
if (raw_request.find(CRLF CRLF) == NPOS)
|
if (raw_request.find(CRLF CRLF) == NPOS)
|
||||||
@@ -96,8 +98,8 @@ void Client::parse_request_headers(std::vector<ServerConfig> &servers)
|
|||||||
|
|
||||||
if (status)
|
if (status)
|
||||||
return;
|
return;
|
||||||
assigned_server = ::_determine_process_server(this, servers);
|
assigned_server = _determine_process_server(this, servers);
|
||||||
assigned_location = ::_determine_location(*assigned_server, _request.abs_path);
|
assigned_location = _determine_location(*assigned_server, _request.abs_path);
|
||||||
_check_request_errors();
|
_check_request_errors();
|
||||||
if (status)
|
if (status)
|
||||||
return;
|
return;
|
||||||
@@ -389,6 +391,7 @@ void Client::_parse_request_fields()
|
|||||||
::str_map_key_tolower(_request.headers);
|
::str_map_key_tolower(_request.headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO : I think its now useless. Probably to delete.
|
||||||
void Client::_parse_port_hostname(std::string host)
|
void Client::_parse_port_hostname(std::string host)
|
||||||
{
|
{
|
||||||
size_t pos;
|
size_t pos;
|
||||||
@@ -453,6 +456,98 @@ void Client::_check_request_errors()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerConfig *Client::_determine_process_server(Client *client, std::vector<ServerConfig> &servers)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Behavior like this :
|
||||||
|
http://nginx.org/en/docs/http/request_processing.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
std::string server_name = client->get_rq_headers("Host");
|
||||||
|
std::cerr << "server_name = " << server_name << "\n";
|
||||||
|
size_t pos = server_name.rfind(':');
|
||||||
|
if (pos != NPOS)
|
||||||
|
server_name.erase(pos);
|
||||||
|
std::cerr << "server_name = " << server_name << "\n";
|
||||||
|
|
||||||
|
std::vector<ServerConfig>::iterator it = servers.begin();
|
||||||
|
std::vector<ServerConfig>::iterator default_server = servers.end();
|
||||||
|
|
||||||
|
while (it != servers.end())
|
||||||
|
{
|
||||||
|
if (it->host == client->get_cl_lsocket()->host
|
||||||
|
&& it->port == client->get_cl_lsocket()->port)
|
||||||
|
{
|
||||||
|
if ( std::find(it->server_name.begin(), it->server_name.end(), server_name) != it->server_name.end() )
|
||||||
|
break;
|
||||||
|
else if (default_server == servers.end())
|
||||||
|
default_server = it;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
if (it != servers.end())
|
||||||
|
return (&(*it));
|
||||||
|
else
|
||||||
|
return (&(*default_server));
|
||||||
|
}
|
||||||
|
|
||||||
|
// const?
|
||||||
|
const LocationConfig *Client::_determine_location(const ServerConfig &server, const std::string &path)
|
||||||
|
{
|
||||||
|
/* RULES ***
|
||||||
|
|
||||||
|
If a path coresponds exactly to a location, use that one
|
||||||
|
if no path coresponds then use the most correct one
|
||||||
|
most correct means the most precise branch that is still above
|
||||||
|
the point we are aiming for
|
||||||
|
|
||||||
|
New Rule for location paths, they never end in /
|
||||||
|
Sooo
|
||||||
|
If we get a url that ends in / ignore the last /
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
std::string uri = path;
|
||||||
|
if (uri[uri.size() - 1] == '/' && uri.size() != 1)
|
||||||
|
uri.erase(uri.size() - 1);
|
||||||
|
|
||||||
|
|
||||||
|
for (std::vector<LocationConfig>::const_iterator it = server.locations.begin(); it != server.locations.end(); it++)
|
||||||
|
{
|
||||||
|
// std::cout << it->path << " -- ";
|
||||||
|
if (it->path.size() > uri.size())
|
||||||
|
continue ;
|
||||||
|
|
||||||
|
if (uri.compare(0, it->path.size(), it->path) == 0)
|
||||||
|
{
|
||||||
|
if (it->path.size() == uri.size())
|
||||||
|
return (&(*it));
|
||||||
|
else if (uri[it->path.size()] == '/')
|
||||||
|
return (&(*it));
|
||||||
|
// this works cuz only ever looking for a / burried in a longer path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (&(server.locations.back()));
|
||||||
|
|
||||||
|
|
||||||
|
// /test/mdr
|
||||||
|
// /test/mdr/
|
||||||
|
// /test/mdrBST
|
||||||
|
|
||||||
|
/////// More stuff to check this still works with
|
||||||
|
|
||||||
|
// /test/test_
|
||||||
|
// /test/test_/
|
||||||
|
// /test/test_deeper
|
||||||
|
// /test/test_deeper/
|
||||||
|
// /test/test_deepei
|
||||||
|
// /test/test_deepei/
|
||||||
|
// /test/test_deeperi
|
||||||
|
// /test/test_deeper/super_deep/
|
||||||
|
// /test/aaaaaaaaaaa/super_deep/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
* OVERLOAD
|
* OVERLOAD
|
||||||
*********************************************/
|
*********************************************/
|
||||||
|
|||||||
@@ -105,15 +105,15 @@ class Client
|
|||||||
void _parse_chunked_body(size_t pos);
|
void _parse_chunked_body(size_t pos);
|
||||||
void _parse_multipart_body(size_t pos);
|
void _parse_multipart_body(size_t pos);
|
||||||
void _check_request_errors();
|
void _check_request_errors();
|
||||||
|
|
||||||
|
ServerConfig*
|
||||||
|
_determine_process_server(Client *client, std::vector<ServerConfig> &servers);
|
||||||
|
const LocationConfig*
|
||||||
|
_determine_location(const ServerConfig &server, const std::string &path);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator==(const Client& lhs, const Client& rhs);
|
bool operator==(const Client& lhs, const Client& rhs);
|
||||||
bool operator==(const Client& lhs, int fd);
|
bool operator==(const Client& lhs, int fd);
|
||||||
bool operator==(int fd, const Client& rhs);
|
bool operator==(int fd, const Client& rhs);
|
||||||
|
|
||||||
// Temporary Global Scope. Probably move to Client in the future.
|
|
||||||
ServerConfig *_determine_process_server(Client *client, std::vector<ServerConfig> &servers);
|
|
||||||
const LocationConfig *_determine_location(const ServerConfig &server, const std::string &path);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -71,39 +71,53 @@ class Webserv
|
|||||||
std::map<std::string, std::string> _mime_types;
|
std::map<std::string, std::string> _mime_types;
|
||||||
|
|
||||||
// accept.cpp
|
// accept.cpp
|
||||||
void _accept_connection(listen_socket &lsocket);
|
void _accept_connection(listen_socket &lsocket);
|
||||||
std::map<std::string, std::string>
|
std::map<std::string, std::string>
|
||||||
_extract_infos(struct sockaddr_in addr);
|
_extract_infos(struct sockaddr_in addr);
|
||||||
// request.cpp
|
// request.cpp
|
||||||
void _request(Client *client);
|
void _request(Client *client);
|
||||||
int _read_request(Client *client);
|
int _read_request(Client *client);
|
||||||
// response.cpp
|
// response.cpp
|
||||||
void _response(Client *client);
|
void _response(Client *client);
|
||||||
int _send_response(Client *client);
|
int _send_response(Client *client);
|
||||||
void _append_base_headers(Client *client);
|
void _append_base_headers(Client *client);
|
||||||
void _construct_response(Client *client);
|
void _construct_response(Client *client);
|
||||||
void _process_method(Client *client, std::string &path);
|
void _process_method(Client *client, std::string &path);
|
||||||
void _insert_status_line(Client *client);
|
|
||||||
void _error_html_response(Client *client);
|
|
||||||
void _append_body(Client *client, const std::string &body, const std::string &file_extension = "");
|
|
||||||
// ServerConfig *_determine_process_server(Client *client); // cant be const cause of error_pages.operator[]
|
|
||||||
// const LocationConfig *_determine_location(const ServerConfig &server, const std::string &path) const;
|
|
||||||
std::string _determine_file_extension(const std::string &path) const;
|
|
||||||
// method_get.cpp
|
|
||||||
|
|
||||||
// move later
|
|
||||||
std::string _replace_url_root(Client *client, std::string path);
|
std::string _replace_url_root(Client *client, std::string path);
|
||||||
|
void _insert_status_line(Client *client);
|
||||||
void _get(Client *client, std::string &path);
|
void _error_html_response(Client *client);
|
||||||
void _get_file(Client *client, const std::string &path);
|
void _append_body(Client *client, const std::string &body, const std::string &file_extension = "");
|
||||||
void _autoindex(Client *client, const std::string &path);
|
// method_get.cpp
|
||||||
|
void _get(Client *client, std::string &path);
|
||||||
|
void _get_file(Client *client, const std::string &path);
|
||||||
|
void _autoindex(Client *client, const std::string &path);
|
||||||
|
std::string _determine_file_extension(const std::string &path) const;
|
||||||
// method_post.cpp
|
// method_post.cpp
|
||||||
void _post(Client *client, const std::string &path);
|
void _post(Client *client, const std::string &path);
|
||||||
void _upload_files(Client *client);
|
void _upload_files(Client *client);
|
||||||
// method_delete.cpp
|
// method_delete.cpp
|
||||||
void _delete(Client *client, const std::string &path);
|
void _delete(Client *client, const std::string &path);
|
||||||
void _delete_file(Client *client, const std::string &path);
|
void _delete_file(Client *client, const std::string &path);
|
||||||
// cgi_script.cpp
|
// epoll_update.cpp
|
||||||
|
int _epoll_update(int fd, uint32_t events, int op);
|
||||||
|
int _epoll_update(int fd, uint32_t events, int op, void *ptr);
|
||||||
|
// signal.cpp
|
||||||
|
void _handle_last_signal();
|
||||||
|
// close.cpp
|
||||||
|
void _close_client(int fd);
|
||||||
|
void _close_all_clients();
|
||||||
|
void _close_all_listen_sockets();
|
||||||
|
void _reopen_lsocket(std::vector<listen_socket>::iterator it);
|
||||||
|
void _handle_epoll_error_lsocket(uint32_t events, std::vector<listen_socket>::iterator it);
|
||||||
|
void _handle_epoll_error_client(uint32_t events, int fd);
|
||||||
|
// init.cpp
|
||||||
|
void _bind(int socket_fd, in_port_t port, std::string host);
|
||||||
|
void _listen(int socket_fd, unsigned int max_connections);
|
||||||
|
void _init_http_status_map();
|
||||||
|
void _init_mime_types_map();
|
||||||
|
// timeout.cpp
|
||||||
|
void _timeout();
|
||||||
|
// cgi.cpp
|
||||||
bool _is_cgi(Client *client, std::string path);
|
bool _is_cgi(Client *client, std::string path);
|
||||||
size_t _cgi_pos(Client *client, std::string &path, size_t pos);
|
size_t _cgi_pos(Client *client, std::string &path, size_t pos);
|
||||||
std::string _exec_cgi(Client *client);
|
std::string _exec_cgi(Client *client);
|
||||||
@@ -117,26 +131,18 @@ class Webserv
|
|||||||
void _check_script_fields(Client *client, std::string & output);
|
void _check_script_fields(Client *client, std::string & output);
|
||||||
void _add_script_body_length_header(std::string & output);
|
void _add_script_body_length_header(std::string & output);
|
||||||
void _remove_body_leading_empty_lines(std::string & output);
|
void _remove_body_leading_empty_lines(std::string & output);
|
||||||
// epoll_update.cpp
|
|
||||||
int _epoll_update(int fd, uint32_t events, int op);
|
|
||||||
int _epoll_update(int fd, uint32_t events, int op, void *ptr);
|
|
||||||
// signal.cpp
|
|
||||||
void _handle_last_signal();
|
|
||||||
// close.cpp
|
|
||||||
void _close_client(int fd);
|
|
||||||
void _close_all_clients();
|
|
||||||
void _close_all_listen_sockets();
|
|
||||||
void _reopen_lsocket(std::vector<listen_socket>::iterator it);
|
|
||||||
void _handle_epoll_error_lsocket(uint32_t events, std::vector<listen_socket>::iterator it);
|
|
||||||
void _handle_epoll_error_client(uint32_t events, int fd);
|
|
||||||
// init.cpp
|
|
||||||
void _bind(int socket_fd, in_port_t port, std::string host);
|
|
||||||
void _listen(int socket_fd, unsigned int max_connections);
|
|
||||||
void _init_http_status_map();
|
|
||||||
void _init_mime_types_map();
|
|
||||||
// timeout.cpp
|
|
||||||
void _timeout();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
HTTP Semantics:
|
||||||
|
https://www.rfc-editor.org/rfc/rfc9110.html
|
||||||
|
https://www.bortzmeyer.org/9110.html
|
||||||
|
https://www.bortzmeyer.org/cours-http-cnam.html
|
||||||
|
HTTP/1.1:
|
||||||
|
https://www.rfc-editor.org/rfc/rfc9112.html
|
||||||
|
https://www.bortzmeyer.org/9112.html
|
||||||
|
CGI:
|
||||||
|
https://www.rfc-editor.org/rfc/rfc3875.html
|
||||||
|
*/
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ void Webserv::_accept_connection(listen_socket &lsocket)
|
|||||||
::fcntl(accepted_fd, F_SETFL, O_NONBLOCK);
|
::fcntl(accepted_fd, F_SETFL, O_NONBLOCK);
|
||||||
|
|
||||||
infos = _extract_infos(addr);
|
infos = _extract_infos(addr);
|
||||||
Client client(accepted_fd, &lsocket, infos["port"], infos["ip"]);
|
Client new_client(accepted_fd, &lsocket, infos["port"], infos["ip"]);
|
||||||
_clients.push_back(client);
|
_clients.push_back(new_client);
|
||||||
_epoll_update(accepted_fd, EPOLLIN, EPOLL_CTL_ADD);
|
_epoll_update(accepted_fd, EPOLLIN, EPOLL_CTL_ADD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
|
|
||||||
#include "Webserv.hpp"
|
#include "Webserv.hpp"
|
||||||
|
/*
|
||||||
|
CGI RFC:
|
||||||
|
https://www.rfc-editor.org/rfc/rfc3875.html
|
||||||
|
*/
|
||||||
|
|
||||||
bool Webserv::_is_cgi(Client *client, std::string path)
|
bool Webserv::_is_cgi(Client *client, std::string path)
|
||||||
{
|
{
|
||||||
@@ -99,23 +103,26 @@ std::string Webserv::_dup_env(std::string var, int i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO : verifier que les variables sont corrects
|
// TODO : verifier que les variables sont corrects
|
||||||
|
/*
|
||||||
|
https://www.rfc-editor.org/rfc/rfc3875#section-4.1
|
||||||
|
*/
|
||||||
void Webserv::_set_env_vector(Client *client, std::vector<std::string> &env_vector)
|
void Webserv::_set_env_vector(Client *client, std::vector<std::string> &env_vector)
|
||||||
{
|
{
|
||||||
env_vector.push_back(_dup_env("AUTH_TYPE")); // authentification not supporte
|
env_vector.push_back(_dup_env("AUTH_TYPE")); // authentification not supporte
|
||||||
env_vector.push_back(_dup_env("CONTENT_LENGTH" , client->get_rq_body().size()));
|
env_vector.push_back(_dup_env("CONTENT_LENGTH" , client->get_rq_body().size()));
|
||||||
env_vector.push_back(_dup_env("CONTENT_TYPE" , client->get_rq_headers("Content-Type")));
|
env_vector.push_back(_dup_env("CONTENT_TYPE" , client->get_rq_headers("Content-Type")));
|
||||||
env_vector.push_back(_dup_env("GATEWAY_INTERFACE" , "CGI/1.1")); // https://www.rfc-editor.org/rfc/rfc387)
|
env_vector.push_back(_dup_env("GATEWAY_INTERFACE" , "CGI/1.1")); // https://www.rfc-editor.org/rfc/rfc3875#section-4.1.4
|
||||||
env_vector.push_back(_dup_env("PATH_INFO" , client->get_rq_script_info()));
|
env_vector.push_back(_dup_env("PATH_INFO" , client->get_rq_script_info())); // LUKE: To Check
|
||||||
env_vector.push_back(_dup_env("PATH_TRANSLATED")); // not supported
|
env_vector.push_back(_dup_env("PATH_TRANSLATED")); // not supported // LUKE: Why not supported ?
|
||||||
env_vector.push_back(_dup_env("QUERY_STRING" , client->get_rq_query()));
|
env_vector.push_back(_dup_env("QUERY_STRING" , client->get_rq_query()));
|
||||||
env_vector.push_back(_dup_env("REMOTE_ADDR" , client->get_cl_ip()));
|
env_vector.push_back(_dup_env("REMOTE_ADDR" , client->get_cl_ip()));
|
||||||
env_vector.push_back(_dup_env("REMOTE_HOST" , client->get_rq_headers("Host"))); // just tes
|
env_vector.push_back(_dup_env("REMOTE_HOST" , client->get_cl_ip())); // equal to REMOTE_ADDR or empty
|
||||||
env_vector.push_back(_dup_env("REMOTE_IDENT")); // authentification not supporte
|
env_vector.push_back(_dup_env("REMOTE_IDENT")); // authentification not supported
|
||||||
env_vector.push_back(_dup_env("REMOTE_USER")); // authentification not supporte
|
env_vector.push_back(_dup_env("REMOTE_USER")); // authentification not supported
|
||||||
env_vector.push_back(_dup_env("REQUEST_METHOD" , client->get_rq_method_str()));
|
env_vector.push_back(_dup_env("REQUEST_METHOD" , client->get_rq_method_str()));
|
||||||
env_vector.push_back(_dup_env("SCRIPT_NAME" , client->get_rq_script_path()));
|
env_vector.push_back(_dup_env("SCRIPT_NAME" , client->get_rq_script_path())); // LUKE: To Check
|
||||||
env_vector.push_back(_dup_env("SERVER_NAME" , client->get_rq_hostname()));
|
env_vector.push_back(_dup_env("SERVER_NAME" , client->get_cl_lsocket()->host));
|
||||||
env_vector.push_back(_dup_env("SERVER_PORT" , client->get_rq_port()));
|
env_vector.push_back(_dup_env("SERVER_PORT" , client->get_cl_lsocket()->port));
|
||||||
env_vector.push_back(_dup_env("SERVER_PROTOCOL" , "HTTP/1.1"));
|
env_vector.push_back(_dup_env("SERVER_PROTOCOL" , "HTTP/1.1"));
|
||||||
env_vector.push_back(_dup_env("SERVER_SOFTWARE" , "Webserv/0.1"));
|
env_vector.push_back(_dup_env("SERVER_SOFTWARE" , "Webserv/0.1"));
|
||||||
env_vector.push_back(_dup_env("REDIRECT_STATUS" , "200"));
|
env_vector.push_back(_dup_env("REDIRECT_STATUS" , "200"));
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
#ifndef HTTP_STATUS_HPP
|
#ifndef HTTP_STATUS_HPP
|
||||||
# define HTTP_STATUS_HPP
|
# define HTTP_STATUS_HPP
|
||||||
|
|
||||||
// https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
/*
|
||||||
|
https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
First version of macro HTML_ERROR(STATUS) dont work with call like this :
|
First version of macro HTML_ERROR(STATUS) dont work with call like this :
|
||||||
|
|||||||
@@ -1,24 +1,13 @@
|
|||||||
|
|
||||||
#include "Webserv.hpp"
|
#include "Webserv.hpp"
|
||||||
|
#define MAX_FILESIZE 1 * MB // unused
|
||||||
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?
|
// const?
|
||||||
void Webserv::_get(Client *client, std::string &path)
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
https://www.rfc-editor.org/rfc/rfc9110.html#name-get
|
https://www.rfc-editor.org/rfc/rfc9110.html#name-get
|
||||||
*/
|
*/
|
||||||
|
void Webserv::_get(Client *client, std::string &path)
|
||||||
|
{
|
||||||
std::cout << "_get()\n";
|
std::cout << "_get()\n";
|
||||||
if (eval_file_type(path) == IS_DIR)
|
if (eval_file_type(path) == IS_DIR)
|
||||||
{
|
{
|
||||||
@@ -42,14 +31,13 @@ void Webserv::_get(Client *client, std::string &path)
|
|||||||
_get_file(client, path);
|
_get_file(client, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
# define MAX_FILESIZE 1 * MB // unused
|
|
||||||
void Webserv::_get_file(Client *client, const std::string &path)
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
std::ios::binary
|
std::ios::binary
|
||||||
https://gcc.gnu.org/onlinedocs/libstdc++/manual/fstreams.html#std.io.filestreams.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.
|
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::ifstream ifd; // For chunk, ifstream directly in struct CLient for multiples read without close() ?
|
||||||
std::stringstream buf;
|
std::stringstream buf;
|
||||||
|
|
||||||
@@ -155,3 +143,11 @@ void Webserv::_autoindex(Client *client, const std::string &path)
|
|||||||
return ;
|
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(""));
|
||||||
|
}
|
||||||
|
|||||||
@@ -119,6 +119,21 @@ void Webserv::_process_method(Client *client, std::string &path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
https://www.rfc-editor.org/rfc/rfc9112.html#name-status-line
|
||||||
|
*/
|
||||||
void Webserv::_insert_status_line(Client *client)
|
void Webserv::_insert_status_line(Client *client)
|
||||||
{
|
{
|
||||||
std::string status_line;
|
std::string status_line;
|
||||||
@@ -176,111 +191,3 @@ void Webserv::_append_body(Client *client, const std::string &body, const std::s
|
|||||||
client->response.append(CRLF);
|
client->response.append(CRLF);
|
||||||
client->response.append(body);
|
client->response.append(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporary Global Scope. Probably move to Client in the future.
|
|
||||||
ServerConfig *_determine_process_server(Client *client, std::vector<ServerConfig> &servers)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Behavior like this :
|
|
||||||
http://nginx.org/en/docs/http/request_processing.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
std::string server_name = client->get_rq_headers("Host");
|
|
||||||
std::cerr << "server_name = " << server_name << "\n";
|
|
||||||
size_t pos = server_name.rfind(':');
|
|
||||||
if (pos != NPOS)
|
|
||||||
server_name.erase(pos);
|
|
||||||
std::cerr << "server_name = " << server_name << "\n";
|
|
||||||
|
|
||||||
std::vector<ServerConfig>::iterator it = servers.begin();
|
|
||||||
std::vector<ServerConfig>::iterator default_server = servers.end();
|
|
||||||
|
|
||||||
while (it != servers.end())
|
|
||||||
{
|
|
||||||
if (it->host == client->get_cl_lsocket()->host
|
|
||||||
&& it->port == client->get_cl_lsocket()->port)
|
|
||||||
{
|
|
||||||
if ( std::find(it->server_name.begin(), it->server_name.end(), server_name) != it->server_name.end() )
|
|
||||||
break;
|
|
||||||
else if (default_server == servers.end())
|
|
||||||
default_server = it;
|
|
||||||
}
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
if (it != servers.end())
|
|
||||||
return (&(*it));
|
|
||||||
else
|
|
||||||
return (&(*default_server));
|
|
||||||
}
|
|
||||||
|
|
||||||
// const?
|
|
||||||
// Temporary Global Scope. Probably move to Client in the future.
|
|
||||||
// is it still TMP Global Scope?
|
|
||||||
const LocationConfig *_determine_location(const ServerConfig &server, const std::string &path)
|
|
||||||
{
|
|
||||||
/* RULES ***
|
|
||||||
|
|
||||||
If a path coresponds exactly to a location, use that one
|
|
||||||
if no path coresponds then use the most correct one
|
|
||||||
most correct means the most precise branch that is still above
|
|
||||||
the point we are aiming for
|
|
||||||
|
|
||||||
New Rule for location paths, they never end in /
|
|
||||||
Sooo
|
|
||||||
If we get a url that ends in / ignore the last /
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
std::string uri = path;
|
|
||||||
if (uri[uri.size() - 1] == '/' && uri.size() != 1)
|
|
||||||
uri.erase(uri.size() - 1);
|
|
||||||
|
|
||||||
|
|
||||||
for (std::vector<LocationConfig>::const_iterator it = server.locations.begin(); it != server.locations.end(); it++)
|
|
||||||
{
|
|
||||||
// std::cout << it->path << " -- ";
|
|
||||||
if (it->path.size() > uri.size())
|
|
||||||
continue ;
|
|
||||||
|
|
||||||
if (uri.compare(0, it->path.size(), it->path) == 0)
|
|
||||||
{
|
|
||||||
if (it->path.size() == uri.size())
|
|
||||||
return (&(*it));
|
|
||||||
else if (uri[it->path.size()] == '/')
|
|
||||||
return (&(*it));
|
|
||||||
// this works cuz only ever looking for a / burried in a longer path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (&(server.locations.back()));
|
|
||||||
|
|
||||||
|
|
||||||
// /test/mdr
|
|
||||||
// /test/mdr/
|
|
||||||
// /test/mdrBST
|
|
||||||
|
|
||||||
/* More stuff to check this still works with ***
|
|
||||||
|
|
||||||
/test/test_
|
|
||||||
/test/test_/
|
|
||||||
/test/test_deeper
|
|
||||||
/test/test_deeper/
|
|
||||||
/test/test_deepei
|
|
||||||
/test/test_deepei/
|
|
||||||
/test/test_deeperi
|
|
||||||
/test/test_deeper/super_deep/
|
|
||||||
/test/aaaaaaaaaaa/super_deep/
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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(""));
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user