|
@ -2,7 +2,6 @@ |
|
|
|
|
|
|
|
|
Socket::Socket(listen_t listen) : _listen(listen) {} |
|
|
Socket::Socket(listen_t listen) : _listen(listen) {} |
|
|
Socket::Socket(int fd, Socket *parent) : _fd(fd), _parent(parent) {} |
|
|
Socket::Socket(int fd, Socket *parent) : _fd(fd), _parent(parent) {} |
|
|
|
|
|
|
|
|
Socket::~Socket(void) { |
|
|
Socket::~Socket(void) { |
|
|
close(_fd); |
|
|
close(_fd); |
|
|
cout << "Socket destroyed!\n"; |
|
|
cout << "Socket destroyed!\n"; |
|
@ -47,8 +46,9 @@ int Socket::launch(void) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Socket::set_fds(void) { |
|
|
void Socket::set_fds(void) { |
|
|
int child_fd; |
|
|
|
|
|
FD_SET(_fd, &_readfds); |
|
|
FD_SET(_fd, &_readfds); |
|
|
|
|
|
|
|
|
|
|
|
int child_fd; |
|
|
for (std::vector<Socket *>::iterator it = _childs.begin(); |
|
|
for (std::vector<Socket *>::iterator it = _childs.begin(); |
|
|
it < _childs.end(); it++) { |
|
|
it < _childs.end(); it++) { |
|
|
child_fd = (*it)->_fd; |
|
|
child_fd = (*it)->_fd; |
|
@ -100,18 +100,68 @@ void Socket::refresh(Env *env) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Server *Socket::choose_server(Env *env, string host) { |
|
|
|
|
|
std::vector<Server *> exact; |
|
|
|
|
|
std::vector<Server *> inrange; |
|
|
|
|
|
std::vector<string> ip_listen; |
|
|
|
|
|
std::vector<string> ip_required; |
|
|
|
|
|
// string ip = inet_ntoa(sock->_address.sin_addr);
|
|
|
|
|
|
// int port = ntohs(sock->_address.sin_port);
|
|
|
|
|
|
|
|
|
|
|
|
// cout << "Which server for " << ip << ":" << port << "?\n";
|
|
|
|
|
|
cout << "Socket: " << _listen.ip << ":" << _listen.port << "\n"; |
|
|
|
|
|
ip_required = split(_listen.ip, '.'); |
|
|
|
|
|
for (std::vector<Server *>::iterator sit = env->_servers.begin(); |
|
|
|
|
|
sit < env->_servers.end(); sit++) { |
|
|
|
|
|
|
|
|
|
|
|
std::vector<listen_t> serv_listens = (*sit)->_listens; |
|
|
|
|
|
for (std::vector<listen_t>::iterator it = serv_listens.begin(); |
|
|
|
|
|
it < serv_listens.end(); it++) { |
|
|
|
|
|
|
|
|
|
|
|
if (_listen.port != (*it).port) |
|
|
|
|
|
continue; |
|
|
|
|
|
if (_listen.ip == (*it).ip) { |
|
|
|
|
|
exact.push_back(*sit); |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
bool is_inrange = true; |
|
|
|
|
|
ip_listen = split((*it).ip, '.'); |
|
|
|
|
|
std::vector<string>::iterator r = ip_required.begin(); |
|
|
|
|
|
for (std::vector<string>::iterator l = ip_listen.begin(); |
|
|
|
|
|
l < ip_listen.end(); l++) { |
|
|
|
|
|
if (*l != *r && *l != "0") |
|
|
|
|
|
is_inrange = false; |
|
|
|
|
|
} |
|
|
|
|
|
if (is_inrange == true) |
|
|
|
|
|
inrange.push_back(*sit); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (exact.size() == 0) { |
|
|
|
|
|
for (std::vector<Server *>::iterator sit = inrange.begin(); |
|
|
|
|
|
sit < inrange.end(); sit++) { |
|
|
|
|
|
if (host == (*sit)->getName()) |
|
|
|
|
|
return *sit; |
|
|
|
|
|
} |
|
|
|
|
|
return inrange.front(); |
|
|
|
|
|
} else |
|
|
|
|
|
return exact.front(); |
|
|
|
|
|
} |
|
|
bool Socket::parseHeader() { |
|
|
bool Socket::parseHeader() { |
|
|
std::vector<string> lines = split(_header, '\n'); |
|
|
std::vector<string> lines = split(_header, '\n'); |
|
|
std::vector<string> line; |
|
|
std::vector<string> line; |
|
|
if (lines.size() > 0) { |
|
|
if (lines.size() > 0) { |
|
|
for (std::vector<string>::iterator it = lines.begin() + 1; it < lines.end(); it++) { |
|
|
for (std::vector<string>::iterator it = lines.begin() + 1; |
|
|
|
|
|
it < lines.end(); it++) { |
|
|
line = split(*it, ' '); |
|
|
line = split(*it, ' '); |
|
|
cout << line.at(0) << "scraped from header\n"; |
|
|
cout << line.at(0) << "scraped from header\n"; |
|
|
_request[line.at(0)] = std::vector<string>(line.begin() + 1, line.end()); |
|
|
_request[line.at(0)] = |
|
|
|
|
|
std::vector<string>(line.begin() + 1, line.end()); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
std::vector<string> method = split(lines.at(0), ' '); |
|
|
std::vector<string> method = split(lines.at(0), ' '); |
|
|
if (method.at(0) == "POST" && _request.find("Content-Length:") == _request.end() && _request.find("Transfer-Encoding:") ==_request.end()) |
|
|
if (method.at(0) == "POST" && |
|
|
|
|
|
_request.find("Content-Length:") == _request.end() && |
|
|
|
|
|
_request.find("Transfer-Encoding:") == _request.end()) |
|
|
return false; |
|
|
return false; |
|
|
_request["Method:"] = method; |
|
|
_request["Method:"] = method; |
|
|
return true; |
|
|
return true; |
|
@ -119,12 +169,17 @@ bool Socket::parseHeader() { |
|
|
|
|
|
|
|
|
bool Socket::getRequest(string paquet) { |
|
|
bool Socket::getRequest(string paquet) { |
|
|
cout << "|===|paquet|===>" << paquet << "|===||\n"; |
|
|
cout << "|===|paquet|===>" << paquet << "|===||\n"; |
|
|
if (paquet.length() < 1) //HTTPS?
|
|
|
if (paquet.length() < 1) // HTTPS?
|
|
|
return false; |
|
|
return false; |
|
|
std::vector<string> lines = split(paquet, '\n'); |
|
|
std::vector<string> lines = split(paquet, '\n'); |
|
|
long chunk_len = (_content.length() > 0 && _request["Transfer-Encoding:"].size() && _request["Transfer-Encoding:"].at(0) == "chunked") ? std::strtol(lines.at(0).substr(1).c_str(), 0, 16) : -1; |
|
|
long chunk_len = |
|
|
|
|
|
(_content.length() > 0 && _request["Transfer-Encoding:"].size() && |
|
|
|
|
|
_request["Transfer-Encoding:"].at(0) == "chunked") |
|
|
|
|
|
? std::strtol(lines.at(0).substr(1).c_str(), 0, 16) |
|
|
|
|
|
: -1; |
|
|
cout << "Chunk length: " << chunk_len << "\n"; |
|
|
cout << "Chunk length: " << chunk_len << "\n"; |
|
|
for (std::vector<string>::iterator it = lines.begin(); it < lines.end(); it++) { |
|
|
for (std::vector<string>::iterator it = lines.begin(); it < lines.end(); |
|
|
|
|
|
it++) { |
|
|
if (*it == "\r" && _content.length() == 0) |
|
|
if (*it == "\r" && _content.length() == 0) |
|
|
this->parseHeader(); |
|
|
this->parseHeader(); |
|
|
if (*it != "\r" && _content.length() == 0) |
|
|
if (*it != "\r" && _content.length() == 0) |
|
@ -136,7 +191,10 @@ bool Socket::getRequest(string paquet) { |
|
|
cout << "Content: \n-|" << _content << "|-\n"; |
|
|
cout << "Content: \n-|" << _content << "|-\n"; |
|
|
if (_content.length() > 0) { |
|
|
if (_content.length() > 0) { |
|
|
_content.resize(_content.length() - 1); |
|
|
_content.resize(_content.length() - 1); |
|
|
if ( _request["Method:"].at(0) == "GET" || (chunk_len == 0 || std::strtoul(_request["Content-Length:"].at(0).c_str(), 0, 10) <= _content.length() ) ) { |
|
|
if (_request["Method:"].at(0) == "GET" || |
|
|
|
|
|
(chunk_len == 0 || |
|
|
|
|
|
std::strtoul(_request["Content-Length:"].at(0).c_str(), 0, 10) <= |
|
|
|
|
|
_content.length())) { |
|
|
cout << "Request received\n"; |
|
|
cout << "Request received\n"; |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
@ -153,8 +211,8 @@ int Socket::answer(Env *env) { |
|
|
std::stringstream answer; |
|
|
std::stringstream answer; |
|
|
answer << "HTTP/1.1"; |
|
|
answer << "HTTP/1.1"; |
|
|
|
|
|
|
|
|
Server *server = env->choose_server(_parent, _request["Host:"].at(0)); |
|
|
Server *server = _parent->choose_server(env, _request["Host:"].at(0)); |
|
|
Route *route = server->get_route(_request["Method:"].at(1)); |
|
|
Route *route = server->choose_route(_request["Method:"].at(1)); |
|
|
string method = _request["Method:"].at(0); |
|
|
string method = _request["Method:"].at(0); |
|
|
std::vector<string> allowed; |
|
|
std::vector<string> allowed; |
|
|
if (method != "GET" && method != "POST" && method != "DELETE") |
|
|
if (method != "GET" && method != "POST" && method != "DELETE") |
|
@ -162,11 +220,14 @@ int Socket::answer(Env *env) { |
|
|
"HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n"); |
|
|
"HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n"); |
|
|
else if ((allowed = route->getHeadersLst()).size() > 0) { |
|
|
else if ((allowed = route->getHeadersLst()).size() > 0) { |
|
|
if (std::find(allowed.begin(), allowed.end(), method) == allowed.end()) |
|
|
if (std::find(allowed.begin(), allowed.end(), method) == allowed.end()) |
|
|
send_answer("HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n"); |
|
|
send_answer( |
|
|
|
|
|
"HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n"); |
|
|
} else if ((allowed = server->getHeadersLst()).size() > 0) { |
|
|
} else if ((allowed = server->getHeadersLst()).size() > 0) { |
|
|
if (std::find(allowed.begin(), allowed.end(), method) == allowed.end()) |
|
|
if (std::find(allowed.begin(), allowed.end(), method) == allowed.end()) |
|
|
send_answer("HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n"); |
|
|
send_answer( |
|
|
|
|
|
"HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
string path = route->correctUri(_request["Method:"].at(1)); |
|
|
string path = route->correctUri(_request["Method:"].at(1)); |
|
|
cout << "Path: " << path << "\n"; |
|
|
cout << "Path: " << path << "\n"; |
|
|
ret = route->getIndex(_request["Method:"].at(1), path); |
|
|
ret = route->getIndex(_request["Method:"].at(1), path); |
|
|