diff --git a/main/new/HTTPMessageController/HTTPConnection.cpp b/main/new/HTTPMessageController/HTTPConnection.cpp index 64fee13..fa6c843 100644 --- a/main/new/HTTPMessageController/HTTPConnection.cpp +++ b/main/new/HTTPMessageController/HTTPConnection.cpp @@ -5,6 +5,7 @@ extern NginxConfig::GlobalConfig _config; HTTPConnection::HTTPConnection(int fd, int block, int server_port, std::string client_ip) { seq = REQUEST; socket_fd = fd; + keep_alive = false; http_data = new HTTPData(block, server_port, client_ip); request_message = new RequestMessage(http_data); response_message = new ResponseMessage(http_data); @@ -19,6 +20,10 @@ HTTPConnection::~HTTPConnection() { close(socket_fd); } +void HTTPConnection::killConnection(void* hc) { + delete reinterpret_cast(hc); +} + int HTTPConnection::getServerBlock(void) { return (this->http_data->getSBlock()); } int HTTPConnection::getFileFd(void) { return (this->file_fd); } int HTTPConnection::getSocketFd(void) { return (this->socket_fd); } @@ -33,6 +38,10 @@ int HTTPConnection::run() { request_message->setMessage(buffer); int request_result = request_message->parsingRequestMessage(); if (request_result == RequestMessage::FINISH_PARSE) { + std::map::iterator res; + if ((res = this->http_data->header_field.find("Connection")) != this->http_data->header_field.end()) + if (res->second == "keep-alive") + keep_alive = true; if (this->http_data->isCGI == true) { cgi_process = new CGIProcess(http_data); cgi_process->run(); @@ -146,6 +155,9 @@ int HTTPConnection::run() { else seq = CGI_READ; } + if (seq == CLOSE && keep_alive == true) { + seq = RE_KEEPALIVE; + } } else if (seq == READY_TO_FILE) { seq = FILE_READ; @@ -173,6 +185,40 @@ int HTTPConnection::run() { else seq = FILE_READ; } + if (seq == CLOSE && keep_alive == true) { + seq = RE_KEEPALIVE; + } + } + else if (seq == RE_KEEPALIVE) { + int backup_block; + int backup_port; + std::string backup_ip; + + backup_block = this->http_data->server_block; + backup_port = this->http_data->server_port; + backup_ip = this->http_data->client_ip; + + if (this->http_data->isCGI == true) + delete cgi_process; + delete request_message; + delete response_message; + delete http_data; + buffer[0] = '\0'; + readLength = -2; + writeLength = -2; + if (file_fd > 0) + file_fd = -2; + if (cgi_output_fd > 0) + cgi_output_fd = -2; + if (cgi_input_fd > 0) + cgi_input_fd = -2; + //keep_alive = false; + //다음 연결에서 keep-alive가 안되는 경우도 있다? + + http_data = new HTTPData(backup_block, backup_port, backup_ip); + request_message = new RequestMessage(http_data); + response_message = new ResponseMessage(http_data); + seq = REQUEST; } return seq; -}; \ No newline at end of file +}; diff --git a/main/new/HTTPMessageController/HTTPConnection.hpp b/main/new/HTTPMessageController/HTTPConnection.hpp index d03e837..861522f 100644 --- a/main/new/HTTPMessageController/HTTPConnection.hpp +++ b/main/new/HTTPMessageController/HTTPConnection.hpp @@ -29,7 +29,8 @@ class HTTPConnection : public ClassController { READY_TO_FILE, FILE_READ, FILE_WRITE, - CLOSE + CLOSE, + RE_KEEPALIVE } Seq; private: @@ -45,10 +46,12 @@ class HTTPConnection : public ClassController { CGIProcess* cgi_process; int readLength; int writeLength; + bool keep_alive; public: HTTPConnection(int fd, int block, int server_port, std::string client_ip); virtual ~HTTPConnection(); + static void killConnection(void *hc); int getServerBlock(void); int getFileFd(void); @@ -59,4 +62,4 @@ class HTTPConnection : public ClassController { int run(); }; -#endif \ No newline at end of file +#endif diff --git a/main/new/ServerProcess/ServerProcess.cpp b/main/new/ServerProcess/ServerProcess.cpp index 59fe629..f66fa08 100644 --- a/main/new/ServerProcess/ServerProcess.cpp +++ b/main/new/ServerProcess/ServerProcess.cpp @@ -40,7 +40,15 @@ void ServerProcess::serverProcess() { kq.addEvent(conn_socket, EVFILT_READ, httpConnection); kq.addEvent(conn_socket, EVFILT_WRITE, httpConnection); kq.disableEvent(conn_socket, EVFILT_WRITE, httpConnection); - timer.init_time(udata); + int keepalive_timeout; + keepalive_timeout = atoi(_config._http._server[server_block]._dir_map["keepalive_timeout"].c_str()); + if (keepalive_timeout < 0) { + keepalive_timeout = atoi(_config._http._dir_map["keepalive_timeout"].c_str()); + if (keepalive_timeout < 0) + keepalive_timeout = 60; + } + timer.init_time(conn_socket, httpConnection, keepalive_timeout); + std::cout << "conn :" << conn_socket << std::endl; } // HTTPConnection 처리 else if (dynamic_cast(udata) != NULL) { @@ -48,14 +56,9 @@ void ServerProcess::serverProcess() { int fd = kq.getFdByEventIndex(i); if (kq.isCloseByEventIndex(i)) { - // if (timer.check_time(udata, hc->getServerBlock())) - // { std::cout << "Client closed socket : " << fd << std::endl; + timer.del_time(hc->getSocketFd()); delete hc; - timer.del_time(udata); - // } - // timer.del_time(udata); - // delete hc; } else { int result = hc->run(); @@ -64,7 +67,6 @@ void ServerProcess::serverProcess() { //std::cout << "kq(r) : " << fd << std::endl; kq.disableEvent(hc->getSocketFd(), EVFILT_READ, udata); kq.enableEvent(hc->getSocketFd(), EVFILT_WRITE, udata); - timer.clean_time(udata); } else if (result == HTTPConnection::BODY_TO_RESPONSE) { kq.disableEvent(hc->getCgiInputFd(), EVFILT_WRITE, udata); kq.enableEvent(hc->getSocketFd(), EVFILT_WRITE, udata); @@ -98,12 +100,14 @@ void ServerProcess::serverProcess() { } else if (result == HTTPConnection::CLOSE) { // 이벤트 제거 // std::cout << "kq(w) : " << fd << std::endl; - // if (timer.check_time(udata, hc->getServerBlock())) - // { - // std::cout << "bye" << std::endl; + std::cout << "bye" << std::endl; + timer.del_time(hc->getSocketFd()); delete hc; - timer.del_time(udata); - // } + } else if (result == HTTPConnection::RE_KEEPALIVE) { + std::cout << "re" << std::endl; + kq.disableEvent(hc->getSocketFd(), EVFILT_WRITE, udata); + kq.enableEvent(hc->getSocketFd(), EVFILT_READ, udata); + timer.clean_time(hc->getSocketFd()); } } } @@ -125,16 +129,14 @@ void ServerProcess::serverProcess() { */ catch (const ErrorHandler& err) { ClassController* udata = reinterpret_cast(kq.getInstanceByEventIndex(i)); - int fd = kq.getFdByEventIndex(i); - timer.del_time(udata); - std::cerr << err.what() << std::endl; - //아마 요 사이에 에러 페이지를 만들고 보내는 코드가 추가되어야 할듯함(였던거) + HTTPConnection* hc = reinterpret_cast(udata); + int fd = hc->getSocketFd(); + timer.del_time(fd); if (fd > 5) { - HTTPConnection* hc = reinterpret_cast(udata); - close(hc->getSocketFd()); - if (hc->getFileFd() > 0) - close (hc->getFileFd()); + // close(hc->getSocketFd()); + // if (hc->getFileFd() > 0) + // close (hc->getFileFd()); delete hc; } std::cerr << err.what() << std::endl; @@ -143,8 +145,13 @@ void ServerProcess::serverProcess() { } } } else { - // std::cout << "waiting..." << std::endl; + std::cout << "waiting..." << std::endl; } + // 여기... + // 필요한거 : hc객체를 쪼갤 무언가 + // 객체를 받는다...?, 인자로 받아야지 + // 저번에 udata객체로 받았다가 망했자너 + timer.check_time(HTTPConnection::killConnection); } return; -}; \ No newline at end of file +}; diff --git a/main/new/TimeController/TimeController.hpp b/main/new/TimeController/TimeController.hpp index aa2637f..206bb81 100644 --- a/main/new/TimeController/TimeController.hpp +++ b/main/new/TimeController/TimeController.hpp @@ -1,47 +1,62 @@ #ifndef TIMECONTROLLER_HPP # define TIMECONTROLLER_HPP -#include +#include #include #include #include #include + class TimeController { private: - std::map timer_list; + struct timer_info + { + void *obj; + time_t start; + int keepalive_timeout; + + }; + std::map timer_list; public: - void init_time(void* id) + void init_time(int id, void *ob, int timeout) { - timer_list[id] = clock(); - // std::cout << "timer start : " << (double)timer_list[id] << std::endl; + timer_info info; + + info.obj = ob; + info.start = time(NULL); + info.keepalive_timeout = timeout; + timer_list[id] = info; +// std::cout << "timer start : " << (double)timer_list[id] << std::endl; } - double get_time(void *id) + double get_time(int id) { - clock_t end; - end = clock(); - return (double(end - timer_list[id])); + time_t end; + end = time(NULL); +// std::cout << "start : " << timer_list[id].start << " end : " << double(end) << std::endl; +// std::cout << "time : " << double(end - timer_list[id].start) << std::endl; + return (double(end - timer_list[id].start)); } - void del_time(void *id) + void del_time(int id) { timer_list.erase(id); - // std::cout << "timer delete" << std::endl; +// std::cout << "timer delete" << std::endl; } - void clean_time(void* id) + void clean_time(int id) { if (timer_list.find(id) != timer_list.end()) - timer_list[id] = clock(); + timer_list[id].start = time(NULL); else return ; - // std::cout << "timer reset" << std::endl; +// std::cout << id << " timer reset : " << timer_list[id].start << std::endl; } - bool find_time(void* id) + bool find_time(int id) { if (timer_list.find(id) != timer_list.end()) return (true); @@ -49,26 +64,31 @@ class TimeController return (false); } - bool check_time(void* id, int block) + //디폴트가 60초 + void check_time(void (*del)(void *)) { - int keepalive_timeout = 0; - - std::map::iterator it; - it = timer_list.find(id); - keepalive_timeout = atoi(_config._http._server[block]._dir_map["keepalive_timeout"].c_str()); - if (keepalive_timeout < 0) { - keepalive_timeout = atoi(_config._http._dir_map["keepalive_timeout"].c_str()); - if (keepalive_timeout < 0) - return (false); + int flag = 0; + std::map::iterator del_it; + for (std::map::iterator it = timer_list.begin(); it != timer_list.end(); it++) + { + if (flag == 1) + { + del(del_it->second.obj); + timer_list.erase(del_it->first); + std::cout << "keepalive_timeout bye" << std::endl; + flag = 0; + } + if (get_time(it->first) >= it->second.keepalive_timeout) { + flag = 1; + del_it = it; + } + } + if (flag == 1) + { + del(del_it->second.obj); + timer_list.erase(del_it->first); + std::cout << "keepalive_timeout bye" << std::endl; } - if (get_time(id) >= keepalive_timeout) - return (false); - return (true); - - - // std::cout << "Asd" << std::endl;// std::cout << "keepalivetimeout1 : " << _config._http._dir_map["keepalive_timeout"] << std::endl; - // std::cout << "keepalivetimeout2 : " << _config._http._server[0]._dir_map["keepalive_timeout"] << std::endl; - // std::cout << "keepalivetimeout2 : " << _config._http._server[1]._dir_map["keepalive_timeout"] << std::endl; } }; diff --git a/main/new/webserv b/main/new/webserv new file mode 100755 index 0000000..f66505a Binary files /dev/null and b/main/new/webserv differ