Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into 106-doxygen을-활용한-소스코드-문서화
Browse files Browse the repository at this point in the history
  • Loading branch information
chanhihi committed Jul 20, 2023
2 parents 5cd79e7 + 253a9dd commit de1be51
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 89 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@
*.DS_Store

doxygen/
webserv
37 changes: 27 additions & 10 deletions srcs/clients/client/include/Client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,46 @@

#define RECEIVE_LEN 1460

/**
* @brief 클라이언트의 상태를 나타내는 enum입니다.
*
* @details
* 1. START : 클라이언트가 생성되었을 때의 상태입니다.
* 2. RECEIVING : 클라이언트가 요청을 수신중일 때의 상태입니다.
* 3. RECEIVE_DONE : 클라이언트가 요청을 완전히 수신했을 때의 상태입니다.
* 4. REQUEST_DONE : 클라이언트가 요청을 완전히 파싱했을 때의 상태입니다.
* 5. PROCESS_RESPONSE : 클라이언트가 응답 생성 및 전송중일 때의 상태입니다.
* 6. END_KEEP_ALIVE : 클라이언트가 Keep-Alive를 종료할 때의 상태입니다.
* 7. END_CLOSE : 클라이언트가 연결을 종료할 때의 상태입니다.
*
* @see Client
* @see EventHandler
* @see IMethod
* @see ICGI
*
* @author chanhihi
* @date 2021-07-21
*/
enum ClientStates {
START,
RECEIVING,

RECEIVE_DONE,
REQUEST_HEAD,
REQUEST_ENTITY,

REQUEST_DONE,
METHOD_SELECT,

PROCESS_RESPONSE,
FILE_READ,
FILE_CGI,
FILE_WRITE,
FILE_DONE,
RESPONSE_DONE,
END_KEEP_ALIVE,
END_CLOSE
};

class Utils;

/**
* @brief 클라이언트를 관리하는 클래스입니다.
*
* @details
* 1. 클라이언트의 상태를 나타내는 enum ClientStates를 가집니다.
*
*/
class Client {
private:
ClientStates _state;
Expand Down
14 changes: 8 additions & 6 deletions srcs/clients/client/src/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Client::~Client(void) {
}

bool Client::checkIfReceiveFinished(ssize_t n) {
_state = RECEIVE_DONE;
return (n < RECEIVE_LEN ||
recv(_sd, Client::_buf, RECEIVE_LEN, MSG_PEEK) == -1);
}
Expand Down Expand Up @@ -89,7 +90,6 @@ void Client::receiveRequest(void) {

void Client::removeTimeOutEventInEventsToAdd(
std::vector<struct kevent> &_eventsToAdd) {
_state = METHOD_SELECT;
_eventsToAdd.pop_back();
}

Expand Down Expand Up @@ -229,17 +229,19 @@ void Client::clear() {
* 2. Request의 connection 헤더 필드가 명시 되어있지 않다면 Response의
* connection 헤더 필드도 keep-alive로 설정합니다.
* 3. Response를 조립합니다.
* 4. state를 PROCESS_RESPONSE로 설정합니다.
*
*/
void Client::setResponseConnection() {
if (_request.getHeaderField("connection") == "close")
_response.setHeaderField("connection", "close");
else
_response.setHeaderField("connection", "keep-alive");
if (_request.getHeaderField("connection") == "close") {
_response.setHeaderField("Connection", "close");
} else {
_response.setHeaderField("Connection", "keep-alive");
}
_response.assembleResponse();
_state = PROCESS_RESPONSE;
}

void Client::setConnectionClose() {
_request.setHeaderField("connection", "close");
_request.setHeaderField("Connection", "close");
}
3 changes: 3 additions & 0 deletions srcs/clients/response/include/Response.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class Response : public IResponse {
void putBody(void);
void configureErrorPages(RequestDts &dts);

void create300Response(RequestDts &dts);
void create400And500Response(RequestDts &dts);

public:
virtual void createExceptionResponse(RequestDts &dts);
bool getResponseFlag(void) const;
Expand Down
137 changes: 69 additions & 68 deletions srcs/clients/response/src/Response.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,114 +11,115 @@ Response::Response(const Response &src) { *this = src; }

Response &Response::operator=(const Response &src) {
if (this != &src) {
this->_response = src._response;
this->_responseFlag = src._responseFlag;
this->_assembleFlag = src._assembleFlag;
this->_statusCode = src._statusCode;
this->_body = src._body;
_response = src._response;
_responseFlag = src._responseFlag;
_assembleFlag = src._assembleFlag;
_statusCode = src._statusCode;
_body = src._body;
}
return (*this);
}

const std::string &Response::getResponse(void) const {
return (this->_response);
}
const std::string &Response::getResponse(void) const { return (_response); }

const std::string &Response::getBody(void) const { return (this->_body); }
const std::string &Response::getBody(void) const { return (_body); }

bool Response::getResponseFlag(void) const { return (this->_responseFlag); }
bool Response::getResponseFlag(void) const { return (_responseFlag); }

Status Response::getStatus(void) { return (this->_statusCode); }
Status Response::getStatus(void) { return (_statusCode); }

std::string &Response::getFieldValue(const std::string &key) {
return (this->_headerFields[key]);
return (_headerFields[key]);
}

void Response::createExceptionResponse(RequestDts &dts) {
resetResponse();
this->_statusCode = *dts.statusCode;
// response for 3xx
if (this->_statusCode >= E_301_MOVED_PERMANENTLY &&
this->_statusCode <= E_308_PERMANENT_REDIRECT) {
this->setHeaderField("Location", *dts.path);
this->assembleResponse();
this->_responseFlag = true;
return;
}
// response for 4xx, 5xx
void Response::create300Response(RequestDts &dts) {
if (dts.path->empty()) *dts.path = "/";
setHeaderField("Location", *dts.path);
assembleResponse();
}

void Response::create400And500Response(RequestDts &dts) {
if (*dts.matchedServer != NULL) {
this->configureErrorPages(dts);
configureErrorPages(dts);
} else {
this->addBody(statusInfo[*dts.statusCode].body);
this->addBody("\r\n");
addBody(statusInfo[*dts.statusCode].body);
addBody("\r\n");
}
this->setHeaderField("Content-Length", itos(this->_body.size()));
this->assembleResponse();
setHeaderField("Content-Length", itos(_body.size()));
assembleResponse();
}

this->_responseFlag = true;
void Response::createExceptionResponse(RequestDts &dts) {
resetResponse();
_statusCode = *dts.statusCode;
if (_statusCode >= E_301_MOVED_PERMANENTLY &&
_statusCode <= E_308_PERMANENT_REDIRECT) {
create300Response(dts);
} else {
create400And500Response(dts);
}
_responseFlag = true;
}

void Response::assembleResponseLine(void) {
this->_response = "HTTP/1.1 ";
this->_response += statusInfo[this->_statusCode].code;
this->_response += " ";
this->_response += statusInfo[this->_statusCode].message;
this->_response += "\r\n";
_response = "HTTP/1.1 ";
_response += statusInfo[_statusCode].code;
_response += " ";
_response += statusInfo[_statusCode].message;
_response += "\r\n";
std::cout << _response << std::endl;
std::cout << _response << std::endl;
}

void Response::resetResponse(void) {
if (this->_responseFlag == false) return;
this->_response.clear();
this->_responseFlag = false;
if (_responseFlag == false) return;
_response.clear();
_responseFlag = false;
}

void Response::setResponseParsed() {
this->_assembleFlag = true;
this->_responseFlag = true;
_assembleFlag = true;
_responseFlag = true;
}
bool Response::isParsed() { return _responseFlag; }

void Response::assembleResponse(void) {
this->assembleResponseLine();
this->putHeaderFields();
this->putBody();
assembleResponseLine();
putHeaderFields();
putBody();
}

void Response::putHeaderFields(void) {
std::map<std::string, std::string>::const_iterator it =
this->_headerFields.begin();
std::map<std::string, std::string>::const_iterator end =
this->_headerFields.end();
std::map<std::string, std::string>::const_iterator it = _headerFields.begin();
std::map<std::string, std::string>::const_iterator end = _headerFields.end();

for (; it != end; ++it) {
this->_response += it->first + ": " + it->second + "\r\n";
_response += it->first + ": " + it->second + "\r\n";
}
}

void Response::putBody(void) {
if (this->_body.empty() == true) {
this->_response += "\r\n";
if (_body.empty() == true) {
_response += "\r\n";
return;
}
this->_response += "\r\n" + this->_body;
_response += "\r\n" + _body;
}

void Response::setStatusCode(Status code) { this->_statusCode = code; }
void Response::setStatusCode(Status code) { _statusCode = code; }

void Response::setHeaderField(const std::string &key,
const std::string &value) {
this->_headerFields[key] = value;
_headerFields[key] = value;
}

void Response::eraseHeaderField(const std::string &key) {
this->_headerFields.erase(key);
_headerFields.erase(key);
}

void Response::addBody(const std::string &str) { this->_body += str; }
void Response::addBody(const std::string &str) { _body += str; }

void Response::setBody(const std::string &str) { this->_body = str; }
void Response::setBody(const std::string &str) { _body = str; }

void Response::configureErrorPages(RequestDts &dts) {
IServerConfig &serverConfig = **dts.matchedServer;
Expand All @@ -131,26 +132,26 @@ void Response::configureErrorPages(RequestDts &dts) {
}
std::ifstream file(path.c_str(), std::ios::in);
if (file.is_open() == false) {
this->setHeaderField("Content-Type", "text/plain");
this->addBody(statusInfo[*dts.statusCode].body);
this->addBody("\r\n");
setHeaderField("Content-Type", "text/plain");
addBody(statusInfo[*dts.statusCode].body);
addBody("\r\n");
return;
} else {
this->setHeaderField("Content-Type", "text/html; charset=UTF-8");
setHeaderField("Content-Type", "text/html; charset=UTF-8");
std::string buff;
while (std::getline(file, buff)) {
this->addBody(buff);
this->addBody("\r\n");
addBody(buff);
addBody("\r\n");
}
file.close();
}
}

void Response::clear() {
this->_response.clear();
this->_responseFlag = false;
this->_assembleFlag = false;
this->_statusCode = E_200_OK;
this->_body.clear();
this->_headerFields.clear();
_response.clear();
_responseFlag = false;
_assembleFlag = false;
_statusCode = E_200_OK;
_body.clear();
_headerFields.clear();
}
28 changes: 28 additions & 0 deletions srcs/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,34 @@
* @copyright Copyright (c) 2023
*/

/**
@mainpage Webserv
@section intro Introduction
- C++ 98 기준으로 작성한 웹서버입니다.
- RFC 7230, 7231, 7232, 7233, 7234, 7235를 준수합니다.
- HTTP/1.1을 지원합니다.
- GET, POST, PUT, DELETE Method를 지원합니다.
- CGI 를 지원합니다.
- 다중 Listen(Config)를 지원합니다.
- 다중 Server(Config)를 지원합니다.
@section Program Webserv
- Config : 설정 파일 내용을 관리하는 정보성 클래스
- Server : 서버를 정보를 담고있는 클래스
- Client : 클라이언트를 정보를 담고있는 클래스
- Request : 클라이언트의 요청을 파싱하는 클래스
@section INOUTPUT 입출력자료
- INPUT : 없음.
- OUTPUT : Hello World 화면출력.
@section CREATEINFO Created Info
- @author chanhihi
- @date 2023-7-17
@section MODIFYINFO Modified Info
- 수정자/수정일 : 수정내역
- chanhihi/2023-7-17 : 최초작성
*/

#include "ServerManager.hpp"

#ifdef LEAKS
Expand Down
18 changes: 13 additions & 5 deletions srcs/server/include/EventHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,25 @@ class EventHandler : public Kqueue {
struct kevent* _currentEvent;
bool _errorFlag;

void checkErrorOnSocket(void);
void acceptClient(void);
void disconnectClient(Client* client);
void registClient(const uintptr_t clientSocket);
void processRequest(Client& client);
void processResponse(Client& client);
void processTimeOut(Client& client);
void disconnectClient(Client* client);

void checkErrorOnSocket(void);

void clientCondition();
void cgiCondition();

void processRequest(Client& client);
void handleTimer(Client& client);
void enactRequestAndCreateResponse(Client& client);
void handleExceptionStatusCode(Client& client);

void processResponse(Client& client);
void validateConnection(Client& client);

void processTimeOut(Client& client);

public:
EventHandler(const std::vector<Server*>& serverVector);
virtual ~EventHandler();
Expand Down

0 comments on commit de1be51

Please sign in to comment.