|
@ -37,14 +37,10 @@ bool Client::getHeader(Env *env, string paquet) { |
|
|
else |
|
|
else |
|
|
paquet.clear(); |
|
|
paquet.clear(); |
|
|
_header += *it + (it + 1 != lines.end() ? "\r\n" : ""); |
|
|
_header += *it + (it + 1 != lines.end() ? "\r\n" : ""); |
|
|
if (_header.find("\r\n\r\n") != string::npos) { |
|
|
if (_header.find("\r\n\r\n") != string::npos) |
|
|
print_block("HEADER: ", _header); |
|
|
return !this->parseHeader(env) |
|
|
if (!this->parseHeader(env)) |
|
|
? false |
|
|
return false; |
|
|
: (paquet.length() > 0 ? getBody(paquet) : true); |
|
|
if (paquet.length() > 0) |
|
|
|
|
|
return getBody(paquet); |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
@ -54,25 +50,19 @@ bool Client::getBody(string paquet) { |
|
|
vec_string::iterator it; |
|
|
vec_string::iterator it; |
|
|
|
|
|
|
|
|
for (it = lines.begin(); it < lines.end(); it++) { |
|
|
for (it = lines.begin(); it < lines.end(); it++) { |
|
|
// cout << "line: " << *it << "\n";
|
|
|
|
|
|
if ((*it).length() && _len <= 0 && |
|
|
if ((*it).length() && _len <= 0 && |
|
|
header_pick("Transfer-Encoding:", 0) == "chunked") { |
|
|
header_pick("Transfer-Encoding:", 0) == "chunked") { |
|
|
_len = std::strtol((*it).c_str(), 0, 16) + 2; |
|
|
_len = std::strtol((*it).c_str(), 0, 16) + 2; |
|
|
_last_chunk = _len == 2 ? true : false; |
|
|
_last_chunk = _len == 2 ? true : false; |
|
|
// +2 for the final \r\n closing chunk
|
|
|
|
|
|
} else if (_len > 0 || it != lines.begin()) { |
|
|
} else if (_len > 0 || it != lines.begin()) { |
|
|
_body += *it + "\r\n"; |
|
|
_body += *it + "\r\n"; |
|
|
_len -= ((*it).length() + 2); |
|
|
_len -= ((*it).length() + 2); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
if (_body.size()) |
|
|
// if (_body.size())
|
|
|
_body.resize(_body.length() - 2); |
|
|
_body.resize(_body.length() - 2); |
|
|
_len += 2; |
|
|
_len += 2; |
|
|
if (_last_chunk && _len == 0) { |
|
|
return (_last_chunk && _len == 0) ? true : false; |
|
|
print_block("BODY: ", _body); |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Client::parseHeader(Env *env) { |
|
|
bool Client::parseHeader(Env *env) { |
|
@ -104,66 +94,55 @@ bool Client::parseHeader(Env *env) { |
|
|
if (len != "") { |
|
|
if (len != "") { |
|
|
_len = std::atoi(len.c_str()); |
|
|
_len = std::atoi(len.c_str()); |
|
|
_last_chunk = true; |
|
|
_last_chunk = true; |
|
|
if (_len > _route->_client_max_body_size) { |
|
|
if (_len > _route->_client_max_body_size) |
|
|
send_error(413); |
|
|
return (send_error(413), false); |
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Client::check_method(void) { |
|
|
bool Client::check_method(void) { |
|
|
vec_string allowed; |
|
|
vec_string allowed; |
|
|
if (_method != "GET" && _method != "POST" && _method != "DELETE" && |
|
|
if ((allowed = _route->_allowed_methods).size() > 0 || |
|
|
_method != "PUT") |
|
|
(allowed = _server->_allowed_methods).size() > 0) |
|
|
send_error(405); |
|
|
return std::find(allowed.begin(), allowed.end(), _method) < |
|
|
else if ((allowed = _route->_allowed_methods).size() > 0) { |
|
|
allowed.end() |
|
|
if (std::find(allowed.begin(), allowed.end(), _method) == allowed.end()) |
|
|
? true |
|
|
send_error(405); |
|
|
: false; |
|
|
else |
|
|
else if (_method == "GET" || _method == "POST" || _method != "DELETE" || |
|
|
return true; |
|
|
_method != "PUT") |
|
|
} 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 (true); |
|
|
return (false); |
|
|
return (false); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
string Client::header_pick(string key, size_t id) { |
|
|
string Client::header_pick(string key, size_t id) { |
|
|
if (_request[key].size() <= id) |
|
|
return _request[key].size() <= id ? "" : _request[key].at(id); |
|
|
return ""; |
|
|
|
|
|
return _request[key].at(id); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Client::answer(void) { |
|
|
void Client::answer(void) { |
|
|
cout << "Method: " << _method << "\n"; |
|
|
print_block("Header: ", _header); |
|
|
cout << "URI: " << _uri << "\n"; |
|
|
print_block("Body: ", _body); |
|
|
cout << "Host: " << _host << "\n"; |
|
|
|
|
|
string ret; |
|
|
string ret; |
|
|
string path = _route->correctUri(_uri); |
|
|
string path = _route->correctUri(_uri); |
|
|
string cgi = |
|
|
string cgi = _route->_cgi.size() ? _route->_cgi[get_extension(path)] |
|
|
_route->_cgi.size() |
|
|
: _server->_cgi.size() ? _server->_cgi[get_extension(path)] |
|
|
? _route->_cgi[get_extension(path)] |
|
|
: ""; |
|
|
: (_server->_cgi.size() ? _server->_cgi[get_extension(path)] : ""); |
|
|
|
|
|
cout << "Path: " << path << "\n"; |
|
|
cout << "Path: " << path << "\n"; |
|
|
if (_method == "PUT") |
|
|
if (_method == "PUT") |
|
|
create_file(path); |
|
|
create_file(path); |
|
|
if (cgi == "") { |
|
|
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); |
|
|
send_cgi(cgi, path); |
|
|
|
|
|
else if (!check_method()) |
|
|
|
|
|
send_error(405); |
|
|
|
|
|
else { |
|
|
|
|
|
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); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Client::create_file(string path) { |
|
|
void Client::create_file(string path) { |
|
@ -186,8 +165,7 @@ void Client::send_cgi(string cgi, string path) { |
|
|
if (!std::ifstream(cgi.c_str()).good()) |
|
|
if (!std::ifstream(cgi.c_str()).good()) |
|
|
return send_error(404); |
|
|
return send_error(404); |
|
|
pipe(fd); |
|
|
pipe(fd); |
|
|
int pid = fork(); |
|
|
if (fork() == 0) { |
|
|
if (pid == 0) { |
|
|
|
|
|
const char **args = new const char *[cgi.length() + path.length() + 2]; |
|
|
const char **args = new const char *[cgi.length() + path.length() + 2]; |
|
|
args[0] = cgi.c_str(); |
|
|
args[0] = cgi.c_str(); |
|
|
args[1] = path.c_str(); |
|
|
args[1] = path.c_str(); |
|
@ -202,7 +180,7 @@ void Client::send_cgi(string cgi, string path) { |
|
|
execve(cgi.c_str(), (char **)args, (char **)env); |
|
|
execve(cgi.c_str(), (char **)args, (char **)env); |
|
|
} |
|
|
} |
|
|
close(fd[1]); |
|
|
close(fd[1]); |
|
|
waitpid(pid, &status, 0); |
|
|
waitpid(-1, &status, 0); |
|
|
char buffer[10000]; |
|
|
char buffer[10000]; |
|
|
buffer[read(fd[0], buffer, 10000)] = 0; |
|
|
buffer[read(fd[0], buffer, 10000)] = 0; |
|
|
ret = string(buffer); |
|
|
ret = string(buffer); |
|
|