From 3c73534084581c398955a6636fcc67384e8c0df6 Mon Sep 17 00:00:00 2001 From: Talyx Date: Sat, 29 Jan 2022 20:12:52 +0300 Subject: [PATCH] update class client, request --- src/Client/Client.cpp | 65 +++++++++++++++++++++++++----- src/Client/Client.hpp | 16 ++++++-- src/Client/Request.cpp | 89 +++++++++++++++++++++++++++++++++++++---- src/Client/Request.hpp | 13 +++++- src/Client/Response.hpp | 4 +- 5 files changed, 161 insertions(+), 26 deletions(-) diff --git a/src/Client/Client.cpp b/src/Client/Client.cpp index ddc9072..d871ab1 100644 --- a/src/Client/Client.cpp +++ b/src/Client/Client.cpp @@ -5,12 +5,14 @@ Client::Client() { this->_fd = -1; + this->_sended = 0; } Client::Client(char *str) { this->_fd = -1; this->_buff = str; + this->_sended = 0; } @@ -19,6 +21,7 @@ Client::Client(char *str, ServerConfig *config) this->_fd = -1; this->_config = config; this->_buff = str; + this->_sended = 0; } @@ -31,7 +34,12 @@ Request Client::getRequest(void) Response Client::getResponse(void) { - return (_Response); + return (_response); +} + +std::string Client::getStrToSend(void) +{ + return (_toSend); } int Client::getFd(void) @@ -49,6 +57,7 @@ void Client::setFd(int fd) this->_fd = fd; } + //-------------------------------------------------Parsing--------------------------------------- int Client::parseRequest(void) @@ -68,23 +77,55 @@ int Client::sendData(int fd, std::string data) { return (send(fd, data.c_str(), data.length(), 0)); } - +//Возвращает истина, если запрос chunked. +bool Client::isChunked(void) +{ + return (_request.getChunked()); +} +// Возвращает истина, если отправлены все данные клиента. +bool Client::allSended(void) +{ + if (_toSend.size() <= _sended) + return (true); + return (false); +} +// Функция увеличивает счетчик на количество BUFFERSIZE. Счетчик - количество байтов отправленных клиенту. +void Client::increaseCounter(void) +{ + _sended += BUFFSIZE; +} +//Генерирует response. Далее респонс можно получить через функцию getStrToSend() int Client::sendResponse(int fd) { - _Response.setData(_request, _config); - _Response.generate(); - _ClientToSend = _Response.getClient(); - _bodyToSend = _Response.getBody(); - _ret = sendData(fd, _ClientToSend); - _ret = sendData(fd, _bodyToSend); + _response.setData(_request, _config); + _response.generate(); + _headerToSend = _response.getClient(); + _bodyToSend = _response.getBody(); + _ret = sendData(fd, _headerToSend + _bodyToSend); return (_ret); } +std::string Client::generateRespons(void) +{ + _response.setData(_request, _config); + _response.generate(); + _headerToSend = _response.getClient(); + _bodyToSend = _response.getBody(); + _toSend = _headerToSend + _bodyToSend; + + return (_toSend); +} + //-------------------------------------------------Error--------------------------------------- //-------------------------------------------------Other--------------------------------------- +bool Client::readyToSend(void) +{ + return(_request.ok()); +} + void Client::printClientInfo(void) { std::map map; @@ -97,14 +138,15 @@ void Client::printClientInfo(void) std::cout << PINK << "host = " << _request.getHost() << ZERO_C << std::endl; std::cout << PINK << "request query = " << _request.getQuery() << ZERO_C << std::endl; std::cout << PINK << "request http versioin = " << _request.getVersion() << ZERO_C << std::endl; - std::cout << YELLOW << "request Client:\n" << _buff << ZERO_C << std::endl; + // std::cout << YELLOW << "request Client:\n" << _buff << ZERO_C << std::endl; std::cout << TURGUOISE << "Client MAP" << ZERO_C << std::endl; for ( it = map.begin(); it != map.end() ; it++) { std::cout << PINK << it->first << BLUE << it->second << ZERO_C << std::endl; - // std::cout << "1\n"; } + std::cout << TURGUOISE << "Client BODY" << ZERO_C << std::endl; + std::cout << BLUE << _request.getBody() << ZERO_C << std::endl; } @@ -116,6 +158,9 @@ void Client::clear(void) _request.clear(); _buff = NULL; _config = NULL; + _bodyToSend = ""; + _headerToSend = ""; + _toSend = ""; } Client::~Client() diff --git a/src/Client/Client.hpp b/src/Client/Client.hpp index 85b91ad..965f77f 100644 --- a/src/Client/Client.hpp +++ b/src/Client/Client.hpp @@ -11,22 +11,25 @@ class Client { private: Request _request; - Response _Response; + Response _response; ServerConfig *_config; private: int _ret; int _fd; + unsigned int _sended; char *_buff; std::string _bodyToSend; - std::string _ClientToSend; + std::string _headerToSend; + std::string _toSend; std::map _errorCode; public: Request getRequest(void); - Response getResponse(void); + Response getResponse(void); + std::string getStrToSend(void); void setRawData(char *); void setFd(int); int getFd(void); @@ -35,10 +38,15 @@ public: int parseRequest(void); void printClientInfo(void); - + + bool readyToSend(void); + bool allSended(void); + bool isChunked(void); int sendResponse(int fd); int sendData(int , std::string data); void clear(void); + void increaseCounter(void); + std::string generateRespons(void); Client(); Client(char *); diff --git a/src/Client/Request.cpp b/src/Client/Request.cpp index 8d2847f..b4a60fd 100644 --- a/src/Client/Request.cpp +++ b/src/Client/Request.cpp @@ -6,6 +6,8 @@ Request::Request() { _row = 0; _ret = 200; + _contentLength = 0; + _chunked = false; } Request::Request(char *str) @@ -13,6 +15,10 @@ Request::Request(char *str) _row = 0; _ret = 200; _data = str; + _head_ok = false; + _body_ok = false; + _chunked = false; + _contentLength = 0; } //-------------------------------------------------Get/Set--------------------------------------- @@ -59,9 +65,12 @@ int Request::getCode(void) } std::map Request::getClientFields(void) { - return (_ClientField); + return (_headerField); +} +bool Request::getChunked(void) +{ + return (_chunked); } - void Request::setData(char *str) { this->_data = str; @@ -118,6 +127,37 @@ int Request::parseStartLine(std::string str) return (_ret); } +void Request::splitData(char *data) +{ + int pos; + std::string str; + + str = data; + if (!_head_ok) + { + pos = str.find("\r\n\r\n"); + if (pos == -1) + { + _ret = 400; + return; + } + _head = str.substr(0, pos) + "\n"; + str.erase(0, pos + 4); + _head_ok = true; + parseHeader(); + if (_contentLength == 0) + _body_ok = true; + } + if (badCode(_ret)) + return ; + else if (!_body_ok) + { + _body += str.substr(0, str.size()); + if (_body.size() >= _contentLength) + _body_ok = true; + } +} + int Request::parseClientfield(std::string str) { int distance; @@ -130,7 +170,7 @@ int Request::parseClientfield(std::string str) key = str.substr(0, distance); std::transform(key.begin(), key.end(), key.begin(), ::tolower); value = str.erase(0, distance + 1); - if (_ClientField.find(key) != _ClientField.end()) + if (_headerField.find(key) != _headerField.end()) { std::cout << RED << "ERROR: double Client-field" << ZERO_C << std::endl; } @@ -138,17 +178,17 @@ int Request::parseClientfield(std::string str) { value = value.erase(0, value.find_first_not_of(WHITESPACE)); value = value.substr(0, value.find_last_not_of(WHITESPACE) + 1); - _ClientField[key] = value; + _headerField[key] = value; } return 200; } -int Request::parseRequest(void) +int Request::parseHeader(void) { std::string line; std::stringstream buffStream; - buffStream << _data; + buffStream << _head; _ret = 200; while (std::getline(buffStream, line, '\n') && !badCode(_ret)) { @@ -163,14 +203,39 @@ int Request::parseRequest(void) return (_ret); } +int Request::parseRequest(void) +{ + if (!_head_ok || !_body_ok) + splitData(_data); + + return (_ret); +} + //-------------------------------------------------Utils--------------------------------------- void Request::copyFromMap() { - _host = _ClientField.find("host")->second; + std::map::iterator it; + int pos; + //host + _host = _headerField.find("host")->second; + + //content-lenght + it = _headerField.find("content-length"); + if (it != _headerField.end()) + _contentLength = atoi(it->second.c_str()); + //chunked + it = _headerField.find("transfer-encoding"); + if (it != _headerField.end()) + { + pos = it->second.find("chunked"); + if ( pos != -1) + _chunked = true; + } } + bool Request::badCode(int code) { if (code == 200) @@ -178,6 +243,11 @@ bool Request::badCode(int code) return true; } +bool Request::ok(void) +{ + return (_head_ok && _body_ok); +} + int Request::isFile(std::string path) { struct stat s; @@ -222,7 +292,10 @@ void Request::clear(void) _fullURI = ""; _version = ""; _location = ""; - _ClientField.clear(); + _head = ""; + _head_ok = false; + _body_ok = false; + _headerField.clear(); _data = NULL; _config = NULL; } diff --git a/src/Client/Request.hpp b/src/Client/Request.hpp index 51ee437..850704e 100644 --- a/src/Client/Request.hpp +++ b/src/Client/Request.hpp @@ -12,8 +12,10 @@ private: int _ret; int _row; + unsigned int _contentLength; std::string _URI; + std::string _head; std::string _body; std::string _host; std::string _query; @@ -21,10 +23,12 @@ private: std::string _fullURI; std::string _version; std::string _location; - std::map _ClientField; + std::map _headerField; ServerConfig *_config; - + bool _head_ok; + bool _body_ok; + bool _chunked; public: std::string getURI(void); std::string getBody(void); @@ -37,6 +41,7 @@ public: ServerConfig *getConfig(void); int getCode(void); std::map getClientFields(void); + bool getChunked(void); void setConfig(ServerConfig *config); void setData(char *); @@ -49,15 +54,19 @@ public: int parseStartLine(std::string); int parseClientfield(std::string); int parseRequest(void); + int parseHeader(void); void parseURI(std::string); void printClientInfo(void); + bool badCode(int); + bool ok(void); int isDir(std::string path); int isFile(std::string path); bool autoindexOn(void); void copyFromMap(void); void clear(void); + void splitData(char *); ~Request(); }; diff --git a/src/Client/Response.hpp b/src/Client/Response.hpp index 10fcb14..5c2b7b5 100644 --- a/src/Client/Response.hpp +++ b/src/Client/Response.hpp @@ -25,8 +25,8 @@ private: public: std::string getClient(void); std::string getBody(void); - static std::string getReasonPhrase(std::string); - static std::string getReasonPhrase(int); + static std::string getReasonPhrase(std::string); + static std::string getReasonPhrase(int); std::string getErrorPage(int code);