Browse Source

save 22-11-13-1

master
nicolas-arnaud 2 years ago
parent
commit
ebc9d32417
  1. 15
      includes/Client.hpp
  2. 7
      srcs/load/Route.cpp
  3. 1
      srcs/load/Server.cpp
  4. 183
      srcs/sock/Client.cpp
  5. 17
      srcs/sock/Master.cpp
  6. 11
      srcs/tools.cpp

15
includes/Client.hpp

@ -8,27 +8,30 @@ class Client {
ip_port_t _ip_port;
Master *_parent;
string _method;
string _uri;
string _host;
string _len;
string _method;
string _uri;
string _host;
int _len;
int _last_len;
Server *_server;
Route *_route;
string _header;
string _content;
string _body;
request_t _request;
public:
Client(int fd, ip_port_t ip_port, Master *parent);
~Client(void);
void clean(void);
bool getRequest(Env *env, string paquet);
bool parseHeader(Env *env);
string header_pick(string key, size_t id);
void answer();
bool check_method();
void create_file(string path);
void send_cgi(string cgi, string path);
void send_cgi_redir(string cgi, string path);
void send_error(int error_code);
void send_answer(string msg);

7
srcs/load/Route.cpp

@ -64,11 +64,11 @@ string Route::getIndex(string uri, string path) {
struct dirent *entry;
struct stat info;
std::vector< string >::iterator it;
cout << "get index(): path=" << path << "\n";
if ((dir = opendir(path.c_str())) == NULL)
if ((dir = opendir(path.c_str())) == NULL) {
return "";
else {
} else {
cout << "get index(): path=" << path << "\n";
content << "<h3 style=\"text-align: center;\">" << path
<< " files :</h3>\n<ul>\n";
while ((entry = readdir(dir)) != NULL) {
@ -89,6 +89,7 @@ string Route::getIndex(string uri, string path) {
}
if (!_autoindex)
return "";
cout << "Getting autoindex\n";
ret << "Content-type: text/html \r\n";
ret << "Content-length: " << content.str().length() << "\r\n";
ret << "\r\n" << content.str();

1
srcs/load/Server.cpp

@ -96,6 +96,7 @@ Route *Server::choose_route(string uri) {
for (std::map< string, Route * >::iterator rit = _routes.begin();
rit != _routes.end(); rit++) {
root = split((*rit).first, "/");
cout << "Route: " << (*rit).first << "\n";
std::vector< string >::iterator root_it = root.begin();
for (std::vector< string >::iterator it = req.begin(); it < req.end();
it++) {

183
srcs/sock/Client.cpp

@ -2,6 +2,7 @@
Client::Client(int fd, ip_port_t ip_port, Master *parent)
: _fd(fd), _ip_port(ip_port), _parent(parent) {
clean();
cout << "New connection, socket fd is " << fd << ", ip is : " << _ip_port.ip
<< ", port : " << _ip_port.port << "\n";
}
@ -19,9 +20,11 @@ void Client::clean(void) {
_method = "";
_uri = "";
_host = "";
_len = 0;
_last_len = -1;
_header = "";
_content = "";
_body = "";
_request.clear();
}
@ -29,84 +32,71 @@ bool Client::getHeader(Env *env, string paquet) {
if (paquet.length() < 1)
send_error(403);
if (header_pick("Method:", 0) != "")
return true;
return getBody(paquet);
std::vector< string > lines = split(paquet, "\r\n");
for (std::vector< string >::iterator it = lines.begin(); it < lines.end();
it++) {
if (*it == "") {
size_t pos = paquet.find("\r\n");
if (pos != string::npos)
paquet.erase(0, pos + 2);
else
paquet.clear();
_header += *it + (it + 1 != lines.end() ? "\r\n" : "");
if (_header.find("\r\n\r\n") != string::npos) {
cout << "Header: \n-|" << _header << "|-\n";
if (!this->parseHeader(env))
return false;
size_t pos = paquet.find("\r\n\r\n");
if (pos != string::npos)
paquet.erase(pos + 4);
return true;
} else
_header += *it + "\r\n";
if (header_pick("Method:", 0) == "GET" ||
header_pick("Method:", 0) == "HEAD")
return true;
else if (paquet.length() > 0) {
// cout << "Remaining paquet: " << paquet.length() << "\n";
return getBody(paquet);
}
cout << "next: " << *it << "\n";
cout << "paquet length remain: " << paquet.length() << "\n";
}
}
_header.resize(_header.length() - 2);
return false;
}
bool Client::getBody(string paquet) {
std::vector< string > lines = split(paquet, "\r\n");
long chunk_len = header_pick("Transfer-Encoding:", 0) == "chunked"
? std::strtol(lines.at(0).c_str(), 0, 16)
: -1;
std::vector< string > lines = split(paquet, "\r\n");
std::vector< string >::iterator it;
cout << paquet << "\n";
for (it = lines.begin(); it < lines.end(); it++) {
if (chunk_len == -1 || it != lines.begin())
_content += *it + "\r\n";
cout << "line: " << *it << "\n";
if ((*it).length() && _len <= 0 &&
header_pick("Transfer-Encoding:", 0) == "chunked") {
_len = std::strtol((*it).c_str(), 0, 16) + 2;
_last_len = _len - 2;
// +2 for the final \r\n closing chunk
} else if (_len > 0 || it != lines.begin()) {
_body += *it + "\r\n";
_len -= ((*it).length() + 2);
}
cout << "Remaining chunk length: " << _len << "\n";
cout << "Previous chunk length: " << _last_len << "\n";
}
_content.resize(_content.length() - 2);
if ((header_pick("Method:", 0) == "GET" && *it == "") ||
(chunk_len == 0 ||
std::strtoul(header_pick("Content-Length:", 0).c_str(), 0, 10) <=
_content.length())) {
cout << "Request received\n";
if (_body.size())
_body.resize(_body.length() - 2);
_len += 2;
cout << "Remaining chunk characters: " << _len << "\n";
if (_last_len == 0 && _len == 0) {
cout << "Content:\n-|" << _body << "|-\n";
return true;
}
return false;
}
bool Client::getRequest(Env *env, string paquet) {
cout << "|===|paquet|===>\n" << paquet << "|===||\n";
if (paquet.length() < 1) // HTTPS?
return false;
std::vector< string > lines = split(paquet, "\n");
long chunk_len = (_content.length() > 0 &&
header_pick("Transfer-Encoding:", 0) == "chunked")
? std::strtol(lines.at(0).c_str(), 0, 16)
: -1;
cout << "Chunk length: " << chunk_len << "\r\n";
for (std::vector< string >::iterator it = lines.begin(); it < lines.end();
it++) {
if (*it == "\r" && header_pick("Method:", 0) == "") {
if (!this->parseHeader(env))
return false;
} else if (*it != "\r" && header_pick("Method:", 0) == "")
_header += *it + "\n";
else if (*it != "\r" && (chunk_len == -1 || it != lines.begin()))
_content += *it + "\n";
string content_length = header_pick("Content_Length:", 0);
if (content_length != "" &&
std::strtoul(content_length.c_str(), 0, 10) <= _body.length()) {
cout << "Content:\n-|" << _body << "|-\n";
return true;
}
cout << "Content: \n-|" << _content << "|-\n";
if (_content.length() > 0) {
_content.resize(_content.length() - 1);
if ((header_pick("Method:", 0) == "GET" && _content.find("\r\n\r\n")) ||
(chunk_len == 0 ||
std::strtoul(header_pick("Content-Length:", 0).c_str(), 0, 10) <=
_content.length())) {
cout << "Request received\n";
return true;
}
} else if (header_pick("Method:", 0) == "")
_header.resize(_header.length() - 1);
return false;
}
bool Client::parseHeader(Env *env) {
cout << "Header: \n-|" << _header << "|-\n";
std::vector< string > lines = split(_header, "\r\n");
std::vector< string > method = split(lines.at(0), " ");
_request["Method:"] = method;
@ -120,7 +110,8 @@ bool Client::parseHeader(Env *env) {
std::vector< string >(line.begin() + 1, line.end());
}
}
if (method.at(0) == "POST" && header_pick("Content-Length:", 0) == "" &&
if ((method.at(0) == "POST" || method.at(0) == "PUT") &&
header_pick("Content-Length:", 0) == "" &&
header_pick("Transfer-Encoding:", 0) != "chunked") {
send_error(400);
return false;
@ -131,22 +122,33 @@ bool Client::parseHeader(Env *env) {
_host = header_pick("Host:", 0);
_server = _parent->choose_server(env, _host);
_route = _server->choose_route(_uri);
_len = header_pick("Content-Length:", 0).c_str();
if (_len != "" && std::atoi(_len.c_str()) > _route->_client_max_body_size) {
send_error(413);
return false;
string len = header_pick("Content-Length:", 0).c_str();
if (len != "") {
_len = std::atoi(len.c_str());
_last_len = 0;
if (_len > _route->_client_max_body_size) {
send_error(413);
return false;
}
}
return true;
}
bool Client::check_method() {
std::vector< string > allowed;
if (_method != "GET" && _method != "POST" && _method != "DELETE")
send_error(405);
else if ((allowed = _route->_allowed_methods).size() > 0 &&
std::find(allowed.begin(), allowed.end(), _method) ==
allowed.end()) {
if (_method != "GET" && _method != "POST" && _method != "DELETE" &&
_method != "PUT")
send_error(405);
else if ((allowed = _route->_allowed_methods).size() > 0) {
if (std::find(allowed.begin(), allowed.end(), _method) == allowed.end())
send_error(405);
else
return true;
} else if ((allowed = _server->_allowed_methods).size() > 0) {
if (std::find(allowed.begin(), allowed.end(), _method) == allowed.end())
send_error(405);
else
return true;
} else
return (true);
return (false);
@ -165,18 +167,37 @@ void Client::answer() {
cout << "URI: " << _uri << "\n";
cout << "Host: " << _host << "\n";
string ret;
if (check_method()) {
string path = _route->correctUri(_uri);
string cgi =
_route->_cgi.size() ? _route->_cgi[get_extension(path)] : "";
if (cgi == "") {
if ((ret = _route->getIndex(_uri, path)) == "" &&
(ret = read_file(path)) == "")
string path = _route->correctUri(_uri);
string cgi =
_route->_cgi.size()
? _route->_cgi[get_extension(path)]
: (_server->_cgi.size() ? _server->_cgi[get_extension(path)] : "");
cout << "Path: " << path << "\n";
if (_method == "PUT")
create_file(path);
if (cgi == "") {
if (check_method()) {
if ((ret = _route->getIndex(_uri, path)) == "")
ret = read_file(path);
if (ret == "404")
send_error(404);
else if (ret == "403")
send_error(403);
else
send_answer("HTTP/1.1 200 OK\r\n" + ret);
} else
send_cgi(cgi, path);
}
} else
send_cgi(cgi, path);
}
void Client::create_file(string path) {
std::ofstream file(path.c_str());
if (!file.good())
send_error(403);
else {
file << _body;
file.close();
send_answer("HTTP/1.1 201 Accepted\r\nContent-Length: 0\r\n\r\n");
}
}
@ -219,7 +240,8 @@ void Client::send_redir(int redir_code, string opt) {
switch (redir_code) {
case 301:
return send_answer(
"HTTTP/1.1 301 Moved Permanently\r\nLocation: " + opt + "\r\n\r\n");
"HTTTP/1.1 301 Moved Permanently\r\nLocation: " + opt +
"\r\n\r\n");
}
}
*/
@ -228,6 +250,9 @@ void Client::send_error(int error_code) {
case 400:
return send_answer(
"HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n");
case 403:
return send_answer(
"HTTP/1.1 403 Forbidden\r\nContent-Length: 0\r\n\r\n");
case 404:
return send_answer(
"HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n");

17
srcs/sock/Master.cpp

@ -54,8 +54,8 @@ Master::Master(ip_port_t list) : _listen(list) {
void Master::set_fds(void) {
FD_SET(_fd, &_readfds);
int child_fd;
for (std::vector< Client * >::iterator it = _childs.begin();
it < _childs.end(); it++) {
child_fd = (*it)->_fd;
@ -74,7 +74,8 @@ void Master::set_fds(void) {
void Master::refresh(Env *env) {
int valread;
int addrlen = sizeof(_address);
char buffer[10000];
char buffer[1000000];
if (FD_ISSET(_fd, &_readfds)) {
int new_socket =
accept(_fd, (struct sockaddr *)&_address, (socklen_t *)&addrlen);
@ -93,16 +94,18 @@ void Master::refresh(Env *env) {
it < _childs.end(); it++) {
child_fd = (*it)->_fd;
if (FD_ISSET(child_fd, &_readfds)) {
valread = read(child_fd, buffer, 10000);
valread = read(child_fd, buffer, 1000000);
buffer[valread] = '\0';
if (valread == 0) {
getpeername(child_fd, (struct sockaddr *)&_address,
(socklen_t *)&addrlen);
delete (*it);
_childs.erase(it);
//} else if ((*it)->getRequest(env, buffer))
} else if ((*it)->getHeader(env, buffer) && (*it)->getBody(buffer))
(*it)->answer();
} else {
// cout << "Paquet:\n-|" << buffer << "|-\n";
if ((*it)->getHeader(env, buffer))
(*it)->answer();
}
}
}
}
@ -131,11 +134,9 @@ Server *Master::choose_server(Env *env, string host) {
ip_required = split(_listen.ip, ".");
for (std::vector< Server * >::iterator sit = env->_servers.begin();
sit < env->_servers.end(); sit++) {
std::vector< ip_port_t > serv_listens = (*sit)->_listens;
for (std::vector< ip_port_t >::iterator it = serv_listens.begin();
it < serv_listens.end(); it++) {
if (_listen.port != (*it).port)
continue;
if (_listen.ip == (*it).ip) {

11
srcs/tools.cpp

@ -226,15 +226,16 @@ string read_file(string path) {
string str;
string content;
std::stringstream ret;
// struct stat info;
/*if (stat(path.c_str(), &info) != 0 || S_ISDIR(info.st_mode)) {
struct stat info;
if (stat(path.c_str(), &info) != 0) {
std::cerr << "stat() error on " << path << ": " << strerror(errno)
<< "\n";
return "";
}*/
return "404";
} else if (S_ISDIR(info.st_mode))
return "404";
std::ifstream file(path.c_str());
if (!file.good())
return "";
return "404";
while (file) {
std::getline(file, str);
content += str + "\n";

Loading…
Cancel
Save