diff --git a/headers.cpp b/headers.cpp index ff50506..8d16142 100644 --- a/headers.cpp +++ b/headers.cpp @@ -19,10 +19,26 @@ Headers::~Headers() { // TODO Auto-generated destructor stub } -void Headers::SetHeader(const std::string& key, const std::string& value) { +void Headers::SetHeader(std::string& key, const std::string& value) { + transform(key.begin(), key.end(), key.begin(), ::tolower); content[key] = value; } +int Headers::ContentLength() const +{ + string len = GetValue("Content-Length"); + if (len.empty())return 0; + return stoi(len); +} + +inline std::string Headers::GetValue(std::string key) const +{ + transform(key.begin(), key.end(), key.begin(), ::tolower); + if (content.count(key) == 0) + return std::string(); + return content.at(key); +} + ostream& operator<<(ostream& out, const chttp::Headers &h) { for (auto &p : h.content) { out << p.first; diff --git a/headers.h b/headers.h index dec6cac..c0c94ec 100644 --- a/headers.h +++ b/headers.h @@ -10,6 +10,7 @@ #include #include +#include #include namespace chttp { @@ -38,7 +39,7 @@ public: Headers(); virtual ~Headers(); - void SetHeader(const std::string& key, const std::string& value); + void SetHeader(std::string& key, const std::string& value); inline const std::unordered_map& Content() const { return content; @@ -48,9 +49,13 @@ public: return content; } + int ContentLength() const; + friend std::ostream& operator<<(std::ostream& out, const Headers &h); private: + inline std::string GetValue(std::string key) const; + std::unordered_map content { }; }; diff --git a/request.h b/request.h index 81ca28c..e7a6e28 100644 --- a/request.h +++ b/request.h @@ -43,8 +43,8 @@ public: Request() = delete; Request(Request_Method method, URL_type url, Http_Version version, - Headers header) : - method(method), url(url), version(version), header(header) { + Headers header, std::string body) : + method(method), url(url), version(version), header(header), request_body(body) { } ~Request(); @@ -77,6 +77,7 @@ private: URL_type url; Http_Version version; Headers header { }; + std::string request_body{ }; }; } /* namespace chttp */ diff --git a/response.cpp b/response.cpp index 6a4ce36..ffe1ce2 100644 --- a/response.cpp +++ b/response.cpp @@ -106,9 +106,9 @@ void Response::WriteSocket(Sock_type sock, const char* buffer, size_t size, if (size == 0) length = strlen(buffer); send(sock, buffer, length, flags); - std::cout << "write to socket:"; - for (size_t i = 0; i < length; ++i) - cout << buffer[i]; + //std::cout << "write to socket:"; + //for (size_t i = 0; i < length; ++i) + // cout << buffer[i]; } inline void Response::CloseSocket(Sock_type sock) diff --git a/router.h b/router.h index e4496aa..e334d36 100644 --- a/router.h +++ b/router.h @@ -16,7 +16,7 @@ namespace chttp { -struct RequestInfo { //TODO:Hash func +struct RequestInfo { Request::URL_type url; Request_Method method; RequestInfo(Request::URL_type url, Request_Method method) : diff --git a/server.cpp b/server.cpp index a52f6f8..dabacef 100644 --- a/server.cpp +++ b/server.cpp @@ -23,6 +23,17 @@ Server::~Server() { // TODO Auto-generated destructor stub } +std::string Server::ReadString(Sock_type sock, size_t count) +{ + char c{}; + string s{}; + for (size_t i = 0; i < count; ++i) { + recv(sock, &c, 1, 0); + s.push_back(c); + } + return s; +} + int Server::GetLine(Sock_type sock, char* buf, int size) { //#ifdef __linux__ int count { }; @@ -117,23 +128,30 @@ Server::Sock_type Server::StartUpSocket(const Port_type& port) { void Server::ProcessRequest(Sock_type clnt_sock) { auto request_string = ReadRequest(clnt_sock); auto request_line = ParseRequestLine(request_string); - Request_Method method = std::get<0>(request_line); + Request_Method method = std::get<0>(request_line); URL_type url = URL{ std::get<1>(request_line) }; std::string url_copy = url.GetURL(); auto count = url_copy.find_first_of('?'); std::string valid_path = url.GetURL().substr(0, count); + Http_Version version = std::get<2>(request_line); + Headers header { }; for (auto it = request_string.begin() + 1; it + 1 != request_string.end(); // ignore the last empty line ++it) { auto pair = GetKeyValuePair(*it); header.SetHeader(pair.first, pair.second); } + + // get request body + int content_length = header.ContentLength(); + std::string request_body = ReadString(clnt_sock, static_cast(content_length)); + cout << "url: " << valid_path << endl; cout << "Headers:\n" << header << endl; // TODO add client info to request - Request request { method, url, version, header }; + Request request{ method, url, version, header, request_body }; Response response { clnt_sock }; RequestInfo request_info { valid_path, method }; @@ -141,7 +159,13 @@ void Server::ProcessRequest(Sock_type clnt_sock) { auto handler = http_router.GetHandler(request_info); handler(request, response); cout << "find existing routers" << endl; - } else { + } + else if (http_router.Contains({ valid_path, Request_Method::ALL })) { + auto handler = http_router.GetHandler(request_info); + handler(request, response); + cout << "find existing routers" << endl; + } + else { cout << "not find existing routers" << endl; response.NotFound(); } diff --git a/server.h b/server.h index edfe13c..947f643 100644 --- a/server.h +++ b/server.h @@ -92,6 +92,7 @@ private: const std::vector& request_data); //Headers ParseRequestHeader(const std::vector& request_data); + std::string ReadString(Sock_type sock, size_t count); int GetLine(Sock_type sock, char* buf, int size); std::string::const_iterator NextWord(std::string::const_iterator begin, std::string::const_iterator end); diff --git a/url.h b/url.h index c8c86ce..c218350 100644 --- a/url.h +++ b/url.h @@ -20,6 +20,8 @@ public: URL(const char* url) :_url(std::string{ url }) {} inline std::string GetURL() const { return _url; } + inline std::string& GetURL() { return _url; } + std::string GetParam(const std::string& key)const; inline bool operator == (const URL& other)const { return this->_url == other._url; }