Skip to content

Commit

Permalink
docs: add doxygen
Browse files Browse the repository at this point in the history
  • Loading branch information
chanhihi committed Jul 20, 2023
1 parent 6c4f46f commit 5cd79e7
Show file tree
Hide file tree
Showing 14 changed files with 331 additions and 28 deletions.
72 changes: 63 additions & 9 deletions srcs/clients/client/src/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,35 @@ bool Client::checkIfReceiveFinished(ssize_t n) {
recv(_sd, Client::_buf, RECEIVE_LEN, MSG_PEEK) == -1);
}

/**
* @brief 클라이언트가 요청을 수신합니다.
*
* @details
* 1. 클라이언트의 현재 상태를 RECEIVING으로 설정합니다.
* 2. recv를 통해 client의 정적 변수 _buf에 수신 데이터를 저장합니다.
* 4. recv로 받은 n의 값이 0보다 작거나 같으면 예외를 발생시킵니다.
* 이는 수신 중 오류가 발생했거나 클라이언트가 연결을 끊었음을 나타냅니다.
* 5. 수신된 데이터를 _recvBuff에 추가합니다.
* 6. _buf를 다시 0으로 초기화합니다.
* 7. 요청을 완전히 수신했는지 checkIfReceiveFinished를 사용하여 확인합니다.
* 만약 완전히 수신되었으면, 루프를 탈출합니다.
*
* @exception Client::RecvFailException
* recv 함수가 -1을 반환하면 발생하는 예외입니다. 이는 수신 중 오류가 발생했음을
* 나타냅니다.
* @exception Client::DisconnectedDuringRecvException
* recv 함수가 0을 반환하면 발생하는 예외입니다. 이는 클라이언트가 요청 수신 중
* 연결을 끊었음을 나타냅니다.
*/
void Client::receiveRequest(void) {
_state = RECEIVING;
while (true) {
ssize_t n = recv(_sd, Client::_buf, RECEIVE_LEN, 0);
if (n <= 0) {
if (n == -1) throw Client::RecvFailException();
if (n == -1)
throw Client::RecvFailException();
else if (n <= 0)
throw Client::DisconnectedDuringRecvException();
}

_recvBuff.insert(_recvBuff.end(), Client::_buf, Client::_buf + n);
std::memset(Client::_buf, 0, RECEIVE_LEN);
if (checkIfReceiveFinished(n) == true) {
Expand Down Expand Up @@ -96,15 +117,32 @@ bool Client::isCgi() { return _request.isCgi(); }
void Client::doRequest() {
_method->doRequest(_request.getRequestParserDts(), _response);
}

/**
* @brief 클라이언트가 응답을 전송합니다.
*
* @details
* 1. Response객체로 부터 전송할 데이터의 response를 받아옵니다.
* 2. send를 통해 SD로 response의 데이터를 로직에 맞춰 전송합니다.
* 3. send 함수의 오류를 처리합니다.
* 4. send로 보낸 n의 값이 (response의 크기 - 마지막으로 보낸 위치)와 다르다면
* 현재 함수에서 탈출합니다.
* 5. Request의 connection 헤더 필드가 close라면 state를 END_CLOSE로 설정합니다.
* 6. 그렇지 않다면 state를 END_KEEP_ALIVE로 설정합니다.
*
* @exception Client::SendFailException
* send 함수가 -1을 반환하면 발생하는 예외입니다. 이는 전송 중 오류가 발생했음을
* 나타냅니다.
* @exception Client::DisconnectedDuringSendException
* send 함수가 0을 반환하면 발생하는 예외입니다. 이는 클라이언트가 응답 전송 중
* 연결을 끊었음을 나타냅니다.
*/
void Client::sendResponse() {
const std::string &response = _response.getResponse();
ssize_t n = send(_sd, response.c_str() + _lastSentPos,
response.size() - _lastSentPos, 0);
if (n <= 0) {
if (n == -1) throw Client::SendFailException();
throw Client::DisconnectedDuringSendException();
}
if (n == -1) throw Client::SendFailException();
if (n <= 0) throw Client::DisconnectedDuringSendException();

if (static_cast<size_t>(n) != response.size() - _lastSentPos) {
_lastSentPos += n;
return;
Expand All @@ -131,7 +169,12 @@ ClientStates Client::getState() const { return _state; }

void Client::setState(ClientStates state) { _state = state; }

uintptr_t Client::getSD() const { return _sd; }
/**
* @brief 소켓 디스크립터를 반환합니다.
*
* @return uintptr_t
*/
uintptr_t Client::getSD() const { return this->_sd; }

const char *Client::RecvFailException::what() const throw() {
return ("error occured in recv()");
Expand Down Expand Up @@ -177,6 +220,17 @@ void Client::clear() {
}
}

/**
* @brief 연결 응답을 설정합니다.
*
* @details
* 1. Request의 connection 헤더 필드가 close라면 Response의 connection 헤더
* 필드도 close로 설정합니다.
* 2. Request의 connection 헤더 필드가 명시 되어있지 않다면 Response의
* connection 헤더 필드도 keep-alive로 설정합니다.
* 3. Response를 조립합니다.
*
*/
void Client::setResponseConnection() {
if (_request.getHeaderField("connection") == "close")
_response.setHeaderField("connection", "close");
Expand Down
11 changes: 10 additions & 1 deletion srcs/main.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
/**
* @file main.cpp
* @brief 프로그램의 시작점입니다.
* @details
* @author chanhihi
* @date 2023-07-20
* @copyright Copyright (c) 2023
*/

#include "ServerManager.hpp"

#ifdef LEAKS
Expand Down Expand Up @@ -35,7 +44,7 @@ int main(int ac, char **av) {
serverManager.promptServer();
serverManager.startServer();
} catch (...) {
std::cout << "Fatal Error" << std::endl;
return (errno);
}
return 0;
}
3 changes: 2 additions & 1 deletion srcs/server/include/EventHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Client;
* @see kevent
* @see FD
*
* @author chanhihi
* @date 2023.07.17
*/
class EventHandler : public Kqueue {
Expand All @@ -50,7 +51,7 @@ class EventHandler : public Kqueue {
void processResponse(Client& client);
void processTimeOut(Client& client);

void clientCondtion();
void clientCondition();
void cgiCondition();

public:
Expand Down
2 changes: 1 addition & 1 deletion srcs/server/include/Server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*
* @see _addr : Socket address, internet style의 서버의 주소를
* 담고있습니다.
* @see _socket : 서버의 소켓을 담고있습니다.
* @see _socket : 서버의 소켓(FD)을 담고있습니다.
* @see _port : 서버의 포트를 담고있습니다.
* @see _host : 서버의 호스트를 담고있습니다.
*
Expand Down
58 changes: 54 additions & 4 deletions srcs/server/src/EventHandler.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* @file EventHandler.cpp
* @brief 서버의 이벤트를 처리하는 소스파일입니다.
* @author chanhihi
* @date 2023-07-20
* @copyright Copyright (c) 2023
*/

#include "EventHandler.hpp"

Expand All @@ -19,6 +26,8 @@
*
* @param serverVector
*
* @return EventHandler
*
* @author chanhihi
* @date 2023.07.17
*/
Expand Down Expand Up @@ -94,7 +103,7 @@ void EventHandler::setCurrentEvent(int i) {
* filter가 EVFILT_TIMER라면 processTimeOut() 함수를 호출합니다.
*
*/
void EventHandler::clientCondtion() {
void EventHandler::clientCondition() {
Client &currClient = *(static_cast<Client *>(this->_currentEvent->udata));
if (this->_currentEvent->filter == EVFILT_READ) {
processRequest(currClient);
Expand All @@ -121,11 +130,11 @@ void EventHandler::cgiCondition() {
*
* @details
* ident가 서버소켓이라면 acceptClient() 함수를 호출합니다.
* ident가 클라이언트 소켓이라면 clientCondtion() 함수를 호출합니다.
* ident가 클라이언트 소켓이라면 clientCondition() 함수를 호출합니다.
* ident가 CGI 소켓이라면 cgiCondition() 함수를 호출합니다.
*
* @see acceptClient()
* @see clientCondtion()
* @see clientCondition()
* @see cgiCondition()
* @see Kqueue::getFdType()
*
Expand All @@ -141,7 +150,7 @@ void EventHandler::branchCondition(void) {
break;
}
case FD_CLIENT: {
clientCondtion();
clientCondition();
break;
}
case FD_CGI:
Expand All @@ -152,6 +161,37 @@ void EventHandler::branchCondition(void) {
}
}

/**
* @brief READ Event로 들어온 Request를 처리합니다.
*
* @details
* 클라이언트로부터 READ Event를 수신할 때 호출됩니다.
* 1. 현재 클라이언트의 상태가 RECEIVING이라면, 클라이언트의 kqueue에서 타임아웃
* 이벤트를 제거합니다.
* 2. 클라이언트 요청 후에 등록 될 요청타임아웃 이벤트를 eventsToAdd에
* 등록합니다.
* 3. 클라이언트로부터 요청을 수신합니다.
* 4. 클라이언트의 요청을 현재이벤트의 Port기준으로 파싱합니다.
* 5. 클라이언트의 상태가 REQUEST_DONE이라면 eventsToAdd에서 타임아웃 이벤트를
* 제거합니다.
* 6. 클라이언트의 상태가 CGI라면 makeAndExecuteCgi() 함수를 호출합니다.
* 7. 클라이언트의 상태가 CGI가 아니라면 어느 Method인지 선택합니다.
* 8. 클라이언트는 Request를 처리합니다.
* 9. 클라이언트는 성공 응답을 생성합니다.
* 10. 해당 클라이언트의 SD를 통해서 READ 이벤트를 비활성화하고, WRITE 이벤트를
* 활성화 합니다.
*
* @see GET
* @see POST
* @see PUT
* @see DELETE
*
* @param currClient
*
* @exception code : status code가 catch되면 예외 응답을 생성합니다.
* @exception std::exception : status code가 아닌 예외가 발생하면 클라이언트를
* 연결을 끊습니다.
*/
void EventHandler::processRequest(Client &currClient) {
try {
if (currClient.getState() == RECEIVING) {
Expand Down Expand Up @@ -189,6 +229,16 @@ void EventHandler::processRequest(Client &currClient) {
};
}

/**
* @brief WRITE Event로 들어온 Response를 처리합니다.
*
* @details
* 클라이언트로부터 WRITE Event를 수신할 때 호출됩니다.
* 1. 현재 클라이언트의 상태가 PROCESS_RESPONSE가 아니라면,
* 클라이언트의 setResponseConnection 함수를 호출합니다.
* 2. 클라이언트 응답을 전송합니다.
* @param currClient
*/
void EventHandler::processResponse(Client &currClient) {
if (currClient.getState() != PROCESS_RESPONSE) {
currClient.setResponseConnection();
Expand Down
8 changes: 8 additions & 0 deletions srcs/server/src/Kqueue.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
/**
* @file Kqueue.cpp
* @brief FD, kevent를 관리하는 소스파일입니다.
* @author TocaTocaToca
* @date 2023-07-20
* @copyright Copyright (c) 2023
*/

#include "Kqueue.hpp"

fd_set Kqueue::_server_fds;
Expand Down
8 changes: 8 additions & 0 deletions srcs/server/src/Server.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
/**
* @file Server.cpp
* @brief 서버를 정의하는 소스파일입니다.
* @author chanhihi
* @date 2023-07-20
* @copyright Copyright (c) 2023
*/

#include "Server.hpp"

#include <arpa/inet.h>
Expand Down
15 changes: 15 additions & 0 deletions srcs/server/src/ServerManager.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/**
* @file ServerManager.cpp
* @brief 서버들을 관리하는 소스파일입니다.
* @details
* ServerManager는 다음과 같은 역할을 합니다.
* 1. Config를 초기화합니다.
* 2. Server를 초기화합니다.
* 3. Server의 정보를 출력합니다.
* 4. Server를 시작합니다.
*
* @author TocaTocaToca
* @date 2023-07-20
* @copyright Copyright (c) 2023
*/

#include "ServerManager.hpp"

#include "Color.hpp"
Expand Down
8 changes: 8 additions & 0 deletions srcs/utils/util/include/Color.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
/**
* @file Color.hpp
* @brief 색상을 출력하기 위한 헤더파일입니다.
* @details 프롬프트 색상 코드 집합입니다.
* @author chanhihi
* @date 2023-07-20
* @copyright Copyright (c) 2023
*/
#pragma once

#define RED "\033[31m"
Expand Down
34 changes: 34 additions & 0 deletions srcs/utils/util/include/Status.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
/**
* @file Status.hpp
* @author chanhihi
* @brief HTTP 응답 코드와 메세지를 정의한 헤더파일입니다.
* @version 0.1
* @date 2023-07-20
*
* @copyright Copyright (c) 2023
*/
#pragma once

/**
* @brief HTTP 응답 코드와 메세지를 저장하는 구조체입니다.
*
* @details
* 1. message : 응답 메세지
* 2. code : 응답 코드
* 3. contentLength : 응답 바디의 길이
* 4. body : 응답 바디
* 5. dummy : 구조체의 크기를 맞추기 위한 dummy
*/
struct msgArray {
const char *message;
const char *code;
Expand All @@ -10,6 +29,21 @@ struct msgArray {
: message(msg), code(c), contentLength(l), body(body) {}
};

/**
* @brief HTTP 응답 코드를 정의한 enum입니다.
*
* @details
* 1xx : Informational
* 2xx : Success
* 3xx : Redirection
* 4xx : Client Error
* 5xx : Server Error
*
* @see https://developer.mozilla.org/ko/docs/Web/HTTP/Status
*
* @author chanhihi
* @date 2021-07-20
*/
enum Status {
E_200_OK,
E_201_CREATED,
Expand Down
10 changes: 9 additions & 1 deletion srcs/utils/util/include/Utils.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
/**
* @file Utils.hpp
* @author chanhihi
* @brief 유틸리티 함수들을 모아놓은 헤더파일입니다.
* @version 0.1
* @date 2023-07-20
*
* @copyright Copyright (c) 2023
*/
#pragma once

#include <netinet/in.h>
#include <sys/event.h>
#include <sys/socket.h>
Expand Down
9 changes: 9 additions & 0 deletions srcs/utils/util/include/Utils.tpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
/**
* @file Utils.tpp
* @brief 유틸리티 함수를 정의한 템플릿 소스파일입니다.
* @details
* @author tocatoca
* @date 2023-07-20
* @copyright Copyright (c) 2023
*/

#pragma once

template <typename T>
Expand Down
Loading

0 comments on commit 5cd79e7

Please sign in to comment.