Skip to content

Commit

Permalink
Merge pull request #41 from Ashes110/29-add-receives-request-and-pars…
Browse files Browse the repository at this point in the history
…e-it

29 add receives request and parse it
  • Loading branch information
ilovenoah authored Feb 4, 2024
2 parents a0eb2d4 + 095afae commit 3fda3dc
Show file tree
Hide file tree
Showing 14 changed files with 470 additions and 36 deletions.
49 changes: 41 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,24 @@ UTILS_DIR = utils/
SOCK_DIR = sockets/
OBJ_DIR = objs/
LOOP_DIR = loop/
REQU_DIR = request/
RESP_DIR = response/

MAIN_NAME = main.cpp
CONF_NAME = Config.cpp Location.cpp Server.cpp
SOCK_NAME = ServerSocket.cpp ClientSocket.cpp
UTILS_NAME = Error.cpp utils.cpp
UTILS_NAME = Error.cpp utils.cpp CaseInsensitiveCompare.cpp
LOOP_NAME = loop.cpp
REQU_NAME = Request.cpp
RESP_NAME = Response.cpp

OBJ_NAME = $(MAIN_NAME:.cpp=.o)
# OBJ_NAME += $(addprefix $(CONF_DIR), $(CONF_NAME:.cpp=.o))
OBJ_NAME += $(addprefix $(CONF_DIR), $(CONF_NAME:.cpp=.o))
OBJ_NAME += $(addprefix $(UTILS_DIR), $(UTILS_NAME:.cpp=.o))
OBJ_NAME += $(addprefix $(LOOP_DIR), $(LOOP_NAME:.cpp=.o))
OBJ_NAME += $(addprefix $(SOCK_DIR), $(SOCK_NAME:.cpp=.o))

OBJ_NAME += $(addprefix $(REQU_DIR), $(REQU_NAME:.cpp=.o))
OBJ_NAME += $(addprefix $(RESP_DIR), $(RESP_NAME:.cpp=.o))
OBJ = $(addprefix $(OBJ_DIR), $(OBJ_NAME))

ifeq ($(UNAME_OS), Linux)
Expand All @@ -34,6 +39,12 @@ else ifeq ($(UNAME_OS), Darwin)
CXXFLAGS += -D_DARWIN
endif

ifeq ($(MAKECMDGOALS), debug)
CXXFLAGS += -D_DEBUG
CXXFLAGS += -fsanitize=address
CXXFLAGS += -g
endif

all: mkdir $(NAME)

$(NAME): $(OBJ)
Expand All @@ -45,11 +56,31 @@ $(OBJ_DIR)%.o: $(SRC_DIR)%.cpp
@echo "##### Creating" [ $@ ] " #####"

mkdir:
@mkdir -p $(OBJ_DIR)$(CONF_DIR)
@mkdir -p $(OBJ_DIR)$(UTILS_DIR)
@mkdir -p $(OBJ_DIR)$(SOCK_DIR)
@mkdir -p $(OBJ_DIR)$(LOOP_DIR)
@echo "##### Creating obj directory #####"
@if [ ! -d "$(OBJ_DIR)$(CONF_DIR)" ]; then \
mkdir -p $(OBJ_DIR)$(CONF_DIR) && \
echo "##### Creating $(OBJ_DIR)$(CONF_DIR) directory #####"; \
fi
@if [ ! -d "$(OBJ_DIR)$(UTILS_DIR)" ]; then \
mkdir -p $(OBJ_DIR)$(UTILS_DIR) && \
echo "##### Creating $(OBJ_DIR)$(UTILS_DIR) directory #####"; \
fi
@if [ ! -d "$(OBJ_DIR)$(SOCK_DIR)" ]; then \
mkdir -p $(OBJ_DIR)$(SOCK_DIR) && \
echo "##### Creating $(OBJ_DIR)$(SOCK_DIR) directory #####"; \
fi
@if [ ! -d "$(OBJ_DIR)$(LOOP_DIR)" ]; then \
mkdir -p $(OBJ_DIR)$(LOOP_DIR) && \
echo "##### Creating $(OBJ_DIR)$(LOOP_DIR) directory #####"; \
fi
@if [ ! -d "$(OBJ_DIR)$(REQU_DIR)" ]; then \
mkdir -p $(OBJ_DIR)$(REQU_DIR) && \
echo "##### Creating $(OBJ_DIR)$(REQU_DIR) directory #####"; \
fi
@if [ ! -d "$(OBJ_DIR)$(RESP_DIR)" ]; then \
mkdir -p $(OBJ_DIR)$(RESP_DIR) && \
echo "##### Creating $(OBJ_DIR)$(RESP_DIR) directory #####"; \
fi


clean:
@$(RM) $(OBJ_DIR)
Expand All @@ -61,4 +92,6 @@ fclean: clean

re: fclean all

debug: all

.PHONY: all mkdir clean fclean re
13 changes: 13 additions & 0 deletions inc/CaseInsensitiveCompare.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef CASEINSENSITIVECOMPARE_HPP
# define CASEINSENSITIVECOMPARE_HPP

#include <string>
#include <algorithm>

class CaseInsensitiveCompare {
private:
public:
bool operator()(std::string const &s1, std::string const &s2) const;
};

#endif
4 changes: 3 additions & 1 deletion inc/ClientSocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,20 @@ class ClientSocket {
std::time_t _lastSendTimestamp;

public:
std::stringstream buffer;
ClientSocket();
ClientSocket(int const fd);
int getFd() const;
void setRevents(short revents);
short getRevents() const;
ClientSocket::csphase tryRecv();
ClientSocket::csphase trySend();
ClientSocket::csphase trySend(std::string const &msg);
void close();
void setPhase(ClientSocket::csphase const phase);
ClientSocket::csphase getPhase() const;
std::time_t getLastSendTimestamp() const;
void setLastSendTimestamp(std::time_t const lastSendTimestamp);
bool findCRLF();
};

#endif
42 changes: 42 additions & 0 deletions inc/Request.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef REQUEST_HPP
#define REQUEST_HPP


#include <string>
#include <map>
#include "ClientSocket.hpp"
#include "CaseInsensitiveCompare.hpp"

class Request {
public:
enum rqphase {
RQLINE,
RQHEADER,
RQBODY,
RQFIN
};
private:
std::string _method;
std::string _path;
std::string _httpVersion;
std::map<std::string, std::string, CaseInsensitiveCompare> _header;
std::string _body;
Request::rqphase _phase;
std::size_t _chunksize;
public:
Request();
void init();
void setReqphase(Request::rqphase const rqphase);
Request::rqphase getReqphase() const;
void setMethod(std::string const &method);
std::string const &getMethod() const;
void setPath(std::string const &path);
std::string const &getPath() const;
void setHttpVersion(std::string const &httpVersion);
std::string const &getHttpVersion() const;
std::string const &getBody() const;
ClientSocket::csphase load(std::stringstream &buffer);
std::string getEntireData() const;
};

#endif
26 changes: 26 additions & 0 deletions inc/Response.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef RESPONSE_HPP
#define RESPONSE_HPP
#include <string>
#include <map>
#include "ClientSocket.hpp"
#include "Config.hpp"
#include "Request.hpp"

class Response {
// public:
// enum rsphase {
// };
private:
std::string _httpVersion;
std::string _status;
std::string _statusMsg;
std::map<std::string, std::string, CaseInsensitiveCompare> _headers;
std::string _body;

public:
Response();
ClientSocket::csphase load(Config const &config, Request const &request);
std::string getEntireData() const;
};

#endif
5 changes: 4 additions & 1 deletion inc/loop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
#include <map>
#include <vector>
#include <utility>
#include "Config.hpp"
#include "ServerSocket.hpp"
#include "ClientSocket.hpp"
#include "utils.hpp"
#include "Request.hpp"
#include "Response.hpp"

bool loop(std::map<int, ServerSocket> &ssmap);
bool loop(std::map<int, ServerSocket> &ssmap, Config const &config);

#endif
3 changes: 3 additions & 0 deletions inc/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

namespace utils {
void putSysError(char const *msg);
std::size_t decStrToSizeT(std::string &str);
std::size_t hexStrToSizeT(std::string &str);
bool findCRLF(std::stringstream &stream);
}

#endif
91 changes: 72 additions & 19 deletions src/loop/loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// return oss.str();
// }

static bool setRevents(std::map<int, ServerSocket> &ssmap, std::map<int, ClientSocket> &csmap) {
static bool setRevents(std::map<int, ServerSocket> &ssmap, std::map<int, ClientSocket*> &csmap) {
std::vector<struct pollfd> pollfds;
for(std::map<int, ServerSocket>::iterator iter = ssmap.begin(); iter != ssmap.end(); ++iter) {
struct pollfd pfd;
Expand All @@ -18,7 +18,7 @@ static bool setRevents(std::map<int, ServerSocket> &ssmap, std::map<int, ClientS
pfd.events = POLLIN;
pollfds.push_back(pfd);
}
for(std::map<int, ClientSocket>::iterator iter = csmap.begin(); iter != csmap.end(); ++iter) {
for(std::map<int, ClientSocket*>::iterator iter = csmap.begin(); iter != csmap.end(); ++iter) {
struct pollfd pfd;
std::memset(&pfd, 0, sizeof(struct pollfd));
pfd.fd = iter->first;
Expand All @@ -31,14 +31,13 @@ static bool setRevents(std::map<int, ServerSocket> &ssmap, std::map<int, ClientS
}
for(std::vector<struct pollfd>::iterator iter = pollfds.begin(); iter != pollfds.end(); ++iter) {
if (ssmap.find(iter->fd) != ssmap.end()) { ssmap[iter->fd].setRevents(iter->revents); }
else if (csmap.find(iter->fd) != csmap.end()) { csmap[iter->fd].setRevents(iter->revents); }
else if (csmap.find(iter->fd) != csmap.end()) { csmap[iter->fd]->setRevents(iter->revents); }
}
return true;
}

static ClientSocket createCsocket(std::pair<int, sockaddr_in> socketInfo) {
ClientSocket cs(socketInfo.first);
return cs;
static ClientSocket *createCsocket(std::pair<int, sockaddr_in> socketInfo) {
return new(std::nothrow) ClientSocket(socketInfo.first);
}

static ClientSocket::csphase detectTimedOutClientSocket(ClientSocket &cs) {
Expand All @@ -49,33 +48,87 @@ static ClientSocket::csphase detectTimedOutClientSocket(ClientSocket &cs) {
return cs.getPhase();
}

bool loop(std::map<int, ServerSocket> &ssmap) {
std::map<int, ClientSocket> csmap;
bool loop(std::map<int, ServerSocket> &ssmap, Config const &config) {
std::map<int, ClientSocket*> csmap;
std::map<int, Request> rqmap;
std::map<int, Response> rsmap;
while(true) {
if (setRevents(ssmap, csmap) == false) { return false; }
for(std::map<int, ServerSocket>::iterator iter = ssmap.begin(); iter != ssmap.end(); ++iter) {
std::pair<int, sockaddr_in> socketInfo = iter->second.tryAccept();
if (socketInfo.first == -1) { continue; }
csmap.insert(std::pair<int, ClientSocket>(socketInfo.first, createCsocket(socketInfo)));
ClientSocket *newCs;
newCs = createCsocket(socketInfo);
if (newCs == NULL) {
utils::putSysError("new");
close(socketInfo.first);
continue;
}
csmap.insert(std::pair<int, ClientSocket*>(socketInfo.first, newCs));
rqmap.insert(std::pair<int, Request>(socketInfo.first, Request()));
}
for (std::map<int, ClientSocket>::iterator iter = csmap.begin(); iter != csmap.end();) {
iter->second.setPhase(detectTimedOutClientSocket(iter->second));
switch (iter->second.getPhase()) {
case ClientSocket::RECV:
iter->second.setPhase(iter->second.tryRecv());
for (std::map<int, ClientSocket*>::iterator iter = csmap.begin(); iter != csmap.end();) {
iter->second->setPhase(detectTimedOutClientSocket(*(iter->second)));
switch (iter->second->getPhase()) {
case ClientSocket::RECV: {
iter->second->setPhase(iter->second->tryRecv());
++iter;
break;
case ClientSocket::SEND:
iter->second.setPhase(iter->second.trySend());
}
case ClientSocket::SEND: {
#if defined(_DEBUG)
std::clog << rqmap[iter->first].getEntireData() << std::endl;
#endif
std::map<int, Response>::iterator rsiter = rsmap.find(iter->first);
std::map<int, Request>::iterator rqiter = rqmap.find(iter->first);
if (rsiter != rsmap.end() && rqiter != rqmap.end()) {
iter->second->setPhase(iter->second->trySend(rsiter->second.getEntireData()));
rsmap.erase(rsiter);
rqiter->second.init();
}
++iter;
break;
case ClientSocket::CLOSE:
std::map<int, ClientSocket>::iterator toErase = iter;
}
case ClientSocket::CLOSE: {
std::map<int, ClientSocket*>::iterator toErase = iter;
std::map<int, Request>::iterator rqiter = rqmap.find(toErase->first);
if (rqiter != rqmap.end()) { rqmap.erase(rqiter); }
++iter;
iter->second.close();
toErase->second->close();
delete toErase->second;
csmap.erase(toErase);
#if defined(_DEBUG)
std::clog << "ClientSocket size: " << csmap.size() << std::endl;
std::clog << "Request size: " << rqmap.size() << std::endl;
std::clog << "Response size: " << rsmap.size() << std::endl;
int checkFd = open("/dev/null", O_RDONLY);
std::clog << "check fd: " << checkFd << std::endl;
close(checkFd);
#endif
break;
}
}
}
for (std::map<int, Request>::iterator iter = rqmap.begin(); iter != rqmap.end(); ++iter) {
std::map<int, ClientSocket*>::iterator csiter = csmap.find(iter->first);
if (csiter != csmap.end() && (utils::findCRLF(csiter->second->buffer) || iter->second.getReqphase() == Request::RQBODY)) {
ClientSocket::csphase nextcsphase = iter->second.load(csiter->second->buffer);
csiter->second->setPhase(nextcsphase);
}
std::map<int, Response>::iterator rsiter = rsmap.find(iter->first);
if (rsiter == rsmap.end() && iter->second.getReqphase() == Request::RQFIN) {
rsmap.insert(std::pair<int, Response>(iter->first, Response()));
}
}
for (std::map<int, Response>::iterator iter = rsmap.begin(); iter != rsmap.end(); ++iter) {
std::map<int, Request>::iterator rqiter = rqmap.find(iter->first);
std::map<int, ClientSocket*>::iterator csiter = csmap.find(iter->first);
if (rqiter != rqmap.end() && csiter != csmap.end()) {
ClientSocket::csphase nextcsphase = iter->second.load(config, rqiter->second);
csiter->second->setPhase(nextcsphase);
}
}

}
return true;
}
6 changes: 4 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@
// return (0);
// }

int main() {
int main(int argc, const char *argv[]) {
ServerSocket ss("127.0.0.1", "8080");
Config config;
config.setServers(argc, argv);
ss.init();
std::map<int, ServerSocket> ssmap;
ssmap.insert(std::pair<int, ServerSocket>(ss.getFd(), ss));
bool test = loop(ssmap);
bool test = loop(ssmap, config);
(void)test;
}
Loading

0 comments on commit 3fda3dc

Please sign in to comment.