Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🛠️ keep-alive timeout main에 추가 #79

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion main/new/HTTPMessageController/HTTPConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -19,6 +20,10 @@ HTTPConnection::~HTTPConnection() {
close(socket_fd);
}

void HTTPConnection::killConnection(void* hc) {
delete reinterpret_cast<HTTPConnection*>(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); }
Expand All @@ -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<std::string, std::string>::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();
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
};
};
7 changes: 5 additions & 2 deletions main/new/HTTPMessageController/HTTPConnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class HTTPConnection : public ClassController {
READY_TO_FILE,
FILE_READ,
FILE_WRITE,
CLOSE
CLOSE,
RE_KEEPALIVE
} Seq;

private:
Expand All @@ -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);
Expand All @@ -59,4 +62,4 @@ class HTTPConnection : public ClassController {
int run();
};

#endif
#endif
53 changes: 30 additions & 23 deletions main/new/ServerProcess/ServerProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,25 @@ 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<HTTPConnection*>(udata) != NULL) {
HTTPConnection* hc = reinterpret_cast<HTTPConnection*>(udata);

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();
Expand All @@ -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);
Expand Down Expand Up @@ -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());
}
}
}
Expand All @@ -125,16 +129,14 @@ void ServerProcess::serverProcess() {
*/
catch (const ErrorHandler& err) {
ClassController* udata = reinterpret_cast<ClassController*>(kq.getInstanceByEventIndex(i));
int fd = kq.getFdByEventIndex(i);
timer.del_time(udata);
std::cerr << err.what() << std::endl;
//아마 요 사이에 에러 페이지를 만들고 보내는 코드가 추가되어야 할듯함(였던거)
HTTPConnection* hc = reinterpret_cast<HTTPConnection*>(udata);
int fd = hc->getSocketFd();
timer.del_time(fd);
if (fd > 5)
{
HTTPConnection* hc = reinterpret_cast<HTTPConnection*>(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;
Expand All @@ -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;
};
};
86 changes: 53 additions & 33 deletions main/new/TimeController/TimeController.hpp
Original file line number Diff line number Diff line change
@@ -1,74 +1,94 @@
#ifndef TIMECONTROLLER_HPP
# define TIMECONTROLLER_HPP

#include <time.h>
#include <ctime>
#include <sys/time.h>
#include <map>
#include <iostream>
#include <string>

class TimeController
{
private:
std::map<void*, clock_t> timer_list;
struct timer_info
{
void *obj;
time_t start;
int keepalive_timeout;

};
std::map<int, timer_info> 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);
else
return (false);
}

bool check_time(void* id, int block)
//디폴트가 60초
void check_time(void (*del)(void *))
{
int keepalive_timeout = 0;

std::map<void*, clock_t>::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<int, timer_info>::iterator del_it;
for (std::map<int, timer_info>::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;
}
};

Expand Down
Binary file added main/new/webserv
Binary file not shown.