diff --git a/Makefile b/Makefile index f0d37a4..ac41cb6 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ SANFLAGS = -fsanitize=address # SANFLAGS = -fsanitize=leak -CXXFLAGS = -Wall -Wextra -Werror -g -std=c++98 -fno-limit-debug-info $(SANFLAGS) +CXXFLAGS = -Wall -Wextra -Werror -g -std=c++98 -fno-limit-debug-info $(SANFLAGS) -DDEBUG CPPFLAGS += -MD -MP diff --git a/curls.sh b/curls.sh new file mode 100644 index 0000000..9c615c5 --- /dev/null +++ b/curls.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +I=0 +while [[ I -lt $1 ]] +do + curl --location --request GET 'http://localhost:8080/g-series-15-3579-laptop_service-manual_en-us.pdf' > /dev/null & + I=$((I + 1)); +done diff --git a/includes/webserv.hpp b/includes/webserv.hpp index 8639449..540c5cd 100644 --- a/includes/webserv.hpp +++ b/includes/webserv.hpp @@ -49,4 +49,13 @@ #include #include + +#ifdef DEBUG +#define DBOUT std::cerr << TURQ +#define ENDL RESET << std::endl +#else +#define DBOUT 0 && std::cerr +#define ENDL RESET << std::endl +#endif + #endif diff --git a/src/Client/Client.cpp b/src/Client/Client.cpp index cda7671..34cbd61 100644 --- a/src/Client/Client.cpp +++ b/src/Client/Client.cpp @@ -5,6 +5,7 @@ Client::Client() { allRead = false; + done = false; this->_fd = -1; this->_sended = 0; } @@ -12,6 +13,7 @@ Client::Client() Client::Client(char *str) { allRead = false; + done = false; this->_fd = -1; this->_buff = str; this->_sended = 0; @@ -21,6 +23,7 @@ Client::Client(char *str) Client::Client(char *str, ServerConfig *config) { allRead = false; + done = false; this->_fd = -1; this->_config = config; this->_buff = str; @@ -40,9 +43,9 @@ Response Client::getResponse(void) return (_response); } -std::string Client::getStrToSend(void) +char *Client::getStrToSend(void) { - return (_toSend); + return (_to_send_char); } int Client::getFd(void) @@ -98,8 +101,8 @@ bool Client::isChunked(void) bool Client::allSended(void) { if (_toSend.size() <= _sended) - return (true); - return (false); + done = true; + return (done); } bool Client::allRecved(void) @@ -134,12 +137,21 @@ int Client::sendResponse(int fd) std::string Client::generateRespons(void) { + size_t len; + _response.setData(_request, _config); _response.generate(); _headerToSend = _response.getHeader(); _bodyToSend = _response.getBody(); _toSend = _headerToSend + _bodyToSend; + + len = _toSend.size(); + response_len = len; + /* _to_send_char = new char[len + 1]; */ + _to_send_char = (char *)malloc(sizeof(char) * (len + 1)); + std::memcpy(_to_send_char, _toSend.c_str(), len + 1); + return (_toSend); } @@ -222,8 +234,10 @@ void Client::clear(void) _bodyToSend = ""; _headerToSend = ""; _toSend = ""; + free(_to_send_char); } Client::~Client() { + DBOUT << "client destructor called" << ENDL; } diff --git a/src/Client/Client.hpp b/src/Client/Client.hpp index dcd92c5..32927ed 100644 --- a/src/Client/Client.hpp +++ b/src/Client/Client.hpp @@ -6,6 +6,7 @@ #include "ServerConfig.hpp" #include "Request.hpp" #include "Response.hpp" +#include class Client { @@ -25,15 +26,28 @@ private: std::string _bodyToSend; std::string _headerToSend; std::string _toSend; + char *_to_send_char; std::map _errorCode; public: bool allRead; + enum e_req_status + { + READING, + WRITING, + ENDED + } req_status; + + int serverfd; + size_t readn; + size_t left; + bool done; + size_t response_len; public: Request getRequest(void); Response getResponse(void); - std::string getStrToSend(void); + char *getStrToSend(void); unsigned int getCounter(void) const; void setRawData(char *); void setFd(int); diff --git a/src/Client/Response.cpp b/src/Client/Response.cpp index e254282..7f841b3 100644 --- a/src/Client/Response.cpp +++ b/src/Client/Response.cpp @@ -66,7 +66,7 @@ std::string Response::getTime(void) gettimeofday(&currTime, NULL); t = gmtime(&currTime.tv_sec); - strftime(buff, 1337, "%a, %d %b %Y %H:%M:%S GTM", t); + strftime(buff, 1337, "%a, %d %b %Y %H:%M:%S GMT", t); return (buff); } diff --git a/src/Server/Server.cpp b/src/Server/Server.cpp index 2bfe5f2..46214a8 100644 --- a/src/Server/Server.cpp +++ b/src/Server/Server.cpp @@ -21,6 +21,18 @@ Server::Server(std::string path) _client = 0; } +void Server::print_epoll_events(unsigned int events) +{ + DBOUT << "Epoll events: "; + if (events & EPOLLIN) + DBOUT << "EPOLLIN "; + if (events & EPOLLOUT) + DBOUT << "EPOLLOUT "; + if (events & EPOLLET) + DBOUT << "EPOLLET "; + DBOUT << ENDL; +} + //----------------------------------------------Send-------------------------------------------------------------------------------------------- //----------------------------------------------Configuration----------------------------------------------------------------------------------- @@ -47,55 +59,58 @@ void Server::readConfig(void) void Server::sendData(Client &client, int fd) { - std::string tmp = client.getStrToSend(); - unsigned int size_diff = tmp.size() - client.getCounter(); - + /* std::string tmp = client.getStrToSend(); */ + char *tmp = client.getStrToSend(); + size_t size_diff = client.response_len - client.getCounter(); + size_t send_len; if (size_diff < BUFFSIZE) - { - tmp = tmp.substr(client.getCounter(), size_diff); - } + send_len = size_diff; else - tmp = tmp.substr(client.getCounter(), BUFFSIZE); + send_len = BUFFSIZE; /* std::cout << YELLO << tmp << RESET << std::endl; */ /* std::cout << GREEN << client.getCounter() << RESET << std::endl; */ - send(fd, tmp.c_str(), tmp.size(), 0); + if (send(fd, tmp + client.getCounter(), send_len, MSG_NOSIGNAL) < 0) + { + DBOUT << RED << "SEND FAILED !@!!!" << ENDL; + client.done = true; + } client.increaseCounter(); } -void Server::readSocket(int fd, std::map &client_map) +void Server::readSocket(Client &client, int fd) { int status; int bytes_read; char buf[BUFFSIZE + 1] = {0}; - std::cout << TURQ << "IN readSocket" << RESET << std::endl; + DBOUT << TURQ << "IN readSocket" << RESET << std::endl; bytes_read = recv(fd, buf, BUFFSIZE, 0); if (bytes_read == 0) { - client_map[fd].allRead = true; + client.allRead = true; return; } - client_map[fd].setRawData(buf); - client_map[fd].increaseRecvCounter(bytes_read); - status = client_map[fd].parseRequest(); + client.setRawData(buf); + client.increaseRecvCounter(bytes_read); + status = client.parseRequest(); // client_map[fd].printClientInfo(); - if ((bytes_read < BUFFSIZE) && client_map[fd].allRecved()) + if ((bytes_read < BUFFSIZE) && client.allRecved()) { - client_map[fd].allRead = true; + client.allRead = true; } - std::cerr << "recvCounter " << client_map[fd].getRecvCounter() << std::endl; - std::cerr << "contentLength " << client_map[fd].getRequest().getContentLength() << std::endl; - std::cerr << "allRead " << client_map[fd].allRead << std::endl; + std::cerr << "recvCounter " << client.getRecvCounter() << std::endl; + std::cerr << "contentLength " << client.getRequest().getContentLength() << std::endl; + std::cerr << "allRead " << client.allRead << std::endl; - std::cout << BLUE << "status is " << Response::getReasonPhrase(status) << RESET << std::endl; + DBOUT << BLUE << "status is " << Response::getReasonPhrase(status) << RESET << std::endl; bzero(buf, BUFFSIZE); } @@ -130,72 +145,34 @@ void Server::start(void) { Socket server_sock(AF_INET, SOCK_STREAM, 0, _port, "127.0.0.1"); std::map client_map; - std::map::iterator client_it; int fd; int ready_num = 0; - unsigned int client_events = EPOLLIN | EPOLLOUT | EPOLLET; - unsigned int server_events = EPOLLIN | EPOLLOUT | EPOLLET; + unsigned int client_events = EPOLLIN; + unsigned int server_events = EPOLLIN; _epoll_fd = epoll_create(1337); checkError(server_sock.init(MAX_CLIENT), "Socket init"); setNonBlock(server_sock.getSocketFd()); setNonBlock(_epoll_fd); - std::cerr << YELLO << "adding server_sock..." << RESET << std::endl; + DBOUT << YELLO << "adding server_sock..." << ENDL; add_to_epoll_list(server_sock.getSocketFd(), server_events); while (1) { - // sending - for (client_it = client_map.begin(); - client_it != client_map.end(); ++client_it) - { - std::cout << TURQ << "IN SEND LOOP" << RESET << std::endl; - Client &client = client_it->second; - - if (!client.allRead && !client.isEmpty()) - { - readSocket(client_it->first, client_map); - } - if (client.readyToSend()) - { - epoll_ctl(_epoll_fd, EPOLL_CTL_DEL, client_it->first, NULL); - std::cout << TURQ << "readyToSend " << client_it->first << RESET << std::endl; - client.generateRespons(); - - sendData(client, client_it->first); - - } - - if ((client.readyToSend() && client.allSended()) || client.isEmpty()) - { - client_map[fd].printClientInfo(); - close(client_it->first); - std::cerr << RED << - "deleting client " - << client_it->first - << - RESET - << std::endl; - client_map.erase(client_it); - } - } - - ready_num = epoll_wait(_epoll_fd, _events, MAX_CLIENT, 100); + ready_num = epoll_wait(_epoll_fd, _events, MAX_CLIENT, -1); /* std::cout << TURQ << "ready_num " << ready_num << RESET << std::endl; */ if (ready_num < 0) throw std::logic_error("epoll_ret"); for (int i = 0; i < ready_num; i++) { - /* if (_events[i].events == 0) */ - /* continue; */ fd = _events[i].data.fd; - /* if (_events[i].data.fd == 0) */ - /* { */ - /* continue; */ - /* } */ + unsigned int events = _events[i].events; + + /* DBOUT << "FD is " << fd << ENDL; */ + /* print_epoll_events(events); */ if (fd == server_sock.getSocketFd()) { @@ -208,16 +185,49 @@ void Server::start(void) } else { - std::cout << TURQ << "IN FOR LOOP" << RESET << std::endl; + /* DBOUT << TURQ << "IN FOR LOOP" << RESET << std::endl; */ /* _client--; */ - readSocket(fd, client_map); + /* client_map[fd]; */ + /* client_map.insert(std::make_pair(fd, Client())); */ + if (events & EPOLLIN) + { + DBOUT << GREEN << "doing readSocket" << ENDL; + readSocket(client_map[fd], fd); + if (client_map[fd].readyToSend()) + { + client_map[fd].generateRespons(); + + struct epoll_event ev; + + ev.events = EPOLLOUT; + ev.data.fd = fd; + assert( epoll_ctl(_epoll_fd, EPOLL_CTL_MOD, fd, &ev) == 0); + DBOUT << GREEN << "rearmed to EPOLLOUT" << ENDL; + } + } + else if (events & EPOLLOUT) + { + /* DBOUT << GREEN << "doing sendData" << ENDL; */ + /* client_map[fd].printClientInfo(); */ + sendData(client_map[fd], fd); + if (client_map[fd].allSended()) + { + epoll_ctl(_epoll_fd, EPOLL_CTL_DEL, fd, NULL); + close(fd); + client_map[fd].clear(); + client_map.erase(fd); + DBOUT << RED << + "deleting client " + << fd + << ENDL; + } + } } } - ready_num = 0; } close(server_sock.getSocketFd()); - std::cerr << "end;" << std::endl; + DBOUT << RED << "end;" << ENDL; } diff --git a/src/Server/Server.hpp b/src/Server/Server.hpp index e418a9d..0c2ebc3 100644 --- a/src/Server/Server.hpp +++ b/src/Server/Server.hpp @@ -7,37 +7,57 @@ #include "Socket.hpp" #include "parse.hpp" + class Client; class Server { -private: - int _port; - int _epoll_fd; - int _client; - struct epoll_event _events[MAX_CLIENT]; - struct sockaddr_in _addres; - std::string _ip; - std::vector _configs; - void add_to_epoll_list(int fd, unsigned int ep_events); + private: + int _port; + int _epoll_fd; + int _client; + struct epoll_event _events[MAX_CLIENT]; + struct sockaddr_in _addres; + std::string _ip; + std::vector _configs; + void add_to_epoll_list(int fd, unsigned int ep_events); -private: - void checkError(int fd, std::string str); - void sendFile(std::string str); - void sendClient(Client head, int); - void sendResponse(Client head, int); - void setNonBlock(int fd); - void sendData(Client &client, int fd); - void readSocket(int fd, std::map &client_map); -public: - Server(); - Server(std::string path); + static void print_epoll_events(unsigned int events); - void readConfig(void); - void setupConfig(void); - void start(void); - void end(void); - ~Server(); + private: + void checkError(int fd, std::string str); + void sendFile(std::string str); + void sendClient(Client head, int); + void sendResponse(Client head, int); + void setNonBlock(int fd); + void sendData(Client &client, int fd); + void readSocket(Client &client, int fd); + + enum e_req_status + { + READING, + WRITING, + ENDED + }; + + typedef struct s_client_status + { + int fd; + int serverfd; + size_t readn; + size_t left; + enum e_req_status req_status; + } t_client_status; + + public: + Server(); + Server(std::string path); + + void readConfig(void); + void setupConfig(void); + void start(void); + void end(void); + ~Server(); }; diff --git a/src/main.cpp b/src/main.cpp index 31ee019..7939772 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,7 @@ #include "parse.hpp" #include "Server.hpp" + int main(int argc, char **argv) { (void)argc; diff --git a/www/errorFolder/images/168.png b/www/errorFolder/images/168.png new file mode 100644 index 0000000..f4b8d1f Binary files /dev/null and b/www/errorFolder/images/168.png differ diff --git a/www/g-series-15-3579-laptop_service-manual_en-us.pdf b/www/g-series-15-3579-laptop_service-manual_en-us.pdf new file mode 100644 index 0000000..9086ea0 Binary files /dev/null and b/www/g-series-15-3579-laptop_service-manual_en-us.pdf differ