diff --git a/autotest/CMakeLists.txt b/autotest/CMakeLists.txt index 7d23b94..f715de3 100644 --- a/autotest/CMakeLists.txt +++ b/autotest/CMakeLists.txt @@ -7,7 +7,7 @@ set(AT_SRCS set(AT_TARGET_NAME webcc_autotest) # Common libraries to link. -set(AT_LIBS webcc ${Boost_LIBRARIES} "${CMAKE_THREAD_LIBS_INIT}") +set(AT_LIBS webcc jsoncpp gtest ${Boost_LIBRARIES} "${CMAKE_THREAD_LIBS_INIT}") if(WEBCC_ENABLE_SSL) set(AT_LIBS ${AT_LIBS} ${OPENSSL_LIBRARIES}) @@ -31,4 +31,4 @@ if(UNIX) endif() add_executable(${AT_TARGET_NAME} ${AT_SRCS}) -target_link_libraries(${AT_TARGET_NAME} webcc jsoncpp gtest ${AT_LIBS}) +target_link_libraries(${AT_TARGET_NAME} ${AT_LIBS}) diff --git a/examples/file_upload_client.cc b/examples/file_upload_client.cc index 819f1f2..8f09b87 100644 --- a/examples/file_upload_client.cc +++ b/examples/file_upload_client.cc @@ -50,15 +50,13 @@ int main(int argc, char* argv[]) { webcc::ClientSession session; try { - //auto r = session.PostFile(url, "file", upload_dir / "remember.txt"); - auto r = session.Request(webcc::RequestBuilder{}.Post(). Url(url). File("file", upload_dir / "remember.txt"). Form("json", "{}", "application/json") ()); - //std::cout << r->content() << std::endl; + std::cout << r->status() << std::endl; } catch (const webcc::Exception& e) { std::cout << "Exception: " << e.what() << std::endl; diff --git a/examples/file_upload_server.cc b/examples/file_upload_server.cc index 1e93b7d..f62cb10 100644 --- a/examples/file_upload_server.cc +++ b/examples/file_upload_server.cc @@ -10,7 +10,7 @@ class FileUploadService : public webcc::RestService { public: void Handle(const webcc::RestRequest& request, - webcc::RestResponse* response) final { + webcc::RestResponse* response) override { if (request.http->method() == "POST") { std::cout << "files: " << request.http->form_parts().size() << std::endl; diff --git a/examples/rest_book_server.cc b/examples/rest_book_server.cc index 701bee9..bed4a0f 100644 --- a/examples/rest_book_server.cc +++ b/examples/rest_book_server.cc @@ -42,11 +42,11 @@ public: protected: // Get a list of books based on query parameters. - void Get(const webcc::UrlQuery& query, webcc::RestResponse* response) final; + void Get(const webcc::UrlQuery& query, webcc::RestResponse* response) override; // Create a new book. void Post(const std::string& request_content, - webcc::RestResponse* response) final; + webcc::RestResponse* response) override; private: // Sleep some seconds before send back the response. @@ -68,16 +68,16 @@ protected: // Get the detailed information of a book. void Get(const webcc::UrlMatches& url_matches, const webcc::UrlQuery& query, - webcc::RestResponse* response) final; + webcc::RestResponse* response) override; // Update a book. void Put(const webcc::UrlMatches& url_matches, const std::string& request_content, - webcc::RestResponse* response) final; + webcc::RestResponse* response) override; // Delete a book. void Delete(const webcc::UrlMatches& url_matches, - webcc::RestResponse* response) final; + webcc::RestResponse* response) override; private: // Sleep some seconds before send back the response. diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 80110f3..fb4db64 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -10,7 +10,7 @@ set(UT_SRCS set(UT_TARGET_NAME webcc_unittest) # Common libraries to link. -set(UT_LIBS webcc ${Boost_LIBRARIES} "${CMAKE_THREAD_LIBS_INIT}") +set(UT_LIBS webcc gtest ${Boost_LIBRARIES} "${CMAKE_THREAD_LIBS_INIT}") if(WEBCC_ENABLE_SSL) set(UT_LIBS ${UT_LIBS} ${OPENSSL_LIBRARIES}) @@ -34,6 +34,6 @@ if(UNIX) endif() add_executable(${UT_TARGET_NAME} ${UT_SRCS}) -target_link_libraries(${UT_TARGET_NAME} webcc gtest ${UT_LIBS}) +target_link_libraries(${UT_TARGET_NAME} ${UT_LIBS}) add_test(${UT_TARGET_NAME} ${UT_TARGET_NAME}) diff --git a/unittest/rest_service_manager_unittest.cc b/unittest/rest_service_manager_unittest.cc index f863e78..6d657d2 100644 --- a/unittest/rest_service_manager_unittest.cc +++ b/unittest/rest_service_manager_unittest.cc @@ -7,7 +7,7 @@ class MyRestService : public webcc::RestService { public: void Handle(const webcc::RestRequest& request, - webcc::RestResponse* response) final { + webcc::RestResponse* response) override { response->status = webcc::Status::kOK; } }; diff --git a/webcc/client_session.cc b/webcc/client_session.cc index b1fc564..bb65d5a 100644 --- a/webcc/client_session.cc +++ b/webcc/client_session.cc @@ -121,36 +121,6 @@ ResponsePtr ClientSession::Patch(const std::string& url, std::string&& data, return Request(builder()); } -ResponsePtr ClientSession::PostFile(const std::string& url, - const std::string& name, const Path& path, - const std::vector& headers) { - RequestBuilder builder; - builder.Post().Url(url); - - SetHeaders(headers, &builder); - - builder.File(name, path); - - return Request(builder()); -} - -ResponsePtr ClientSession::PostFiles(const std::string& url, - const std::map& paths, - const std::vector& headers) { - assert(!paths.empty()); - - RequestBuilder builder; - builder.Post().Url(url); - - SetHeaders(headers, &builder); - - for (auto& pair : paths) { - builder.File(pair.first, pair.second); - } - - return Request(builder()); -} - void ClientSession::InitHeaders() { using namespace headers; diff --git a/webcc/client_session.h b/webcc/client_session.h index b8b6fcd..15e76fd 100644 --- a/webcc/client_session.h +++ b/webcc/client_session.h @@ -79,16 +79,6 @@ public: ResponsePtr Patch(const std::string& url, std::string&& data, bool json, const std::vector& headers = {}); - // Post a file. - ResponsePtr PostFile(const std::string& url, const std::string& name, - const Path& path, - const std::vector& headers = {}); - - // Post multiple files. - ResponsePtr PostFiles(const std::string& url, - const std::map& paths, - const std::vector& headers = {}); - private: void InitHeaders(); diff --git a/webcc/common.cc b/webcc/common.cc index 31544a4..3c79922 100644 --- a/webcc/common.cc +++ b/webcc/common.cc @@ -6,6 +6,7 @@ #include "boost/filesystem/fstream.hpp" #include "webcc/logger.h" +#include "webcc/utility.h" namespace bfs = boost::filesystem; @@ -24,33 +25,21 @@ const char CRLF[] = { '\r', '\n' }; // ----------------------------------------------------------------------------- -bool Split2(const std::string& str, char token, std::string* part1, - std::string* part2) { - std::size_t pos = str.find(token); - if (pos == std::string::npos) { +// Read entire file into string. +static bool ReadFile(const Path& path, std::string* output) { + // Flag "ate": seek to the end of stream immediately after open. + bfs::ifstream stream{ path, std::ios::binary | std::ios::ate }; + if (stream.fail()) { return false; } - *part1 = str.substr(0, pos); - *part2 = str.substr(pos + 1); - - boost::trim(*part1); - boost::trim(*part2); - - return true; -} - -bool ReadFile(const Path& path, std::string* output) { - bfs::ifstream ifs{ path, std::ios::binary | std::ios::ate }; - if (!ifs) { + auto size = stream.tellg(); + output->resize(static_cast(size), '\0'); + stream.seekg(std::ios::beg); + stream.read(&(*output)[0], size); + if (stream.fail()) { return false; } - - auto size = ifs.tellg(); - output->resize(static_cast(size), '\0'); - ifs.seekg(0); - ifs.read(&(*output)[0], size); // TODO: Error handling - return true; } diff --git a/webcc/common.h b/webcc/common.h index 03140da..04979f1 100644 --- a/webcc/common.h +++ b/webcc/common.h @@ -21,15 +21,6 @@ using Payload = std::vector; // ----------------------------------------------------------------------------- -// Split a string to two parts by the given token. -bool Split2(const std::string& str, char token, std::string* part1, - std::string* part2); - -// Read entire file into string. -bool ReadFile(const Path& path, std::string* output); - -// ----------------------------------------------------------------------------- - using Header = std::pair; class Headers { diff --git a/webcc/request.h b/webcc/request.h index 5daeb83..543842c 100644 --- a/webcc/request.h +++ b/webcc/request.h @@ -68,7 +68,7 @@ public: } // Prepare payload. - void Prepare() final; + void Prepare() override; private: void CreateStartLine(); diff --git a/webcc/request_parser.cc b/webcc/request_parser.cc index d872b7e..e050254 100644 --- a/webcc/request_parser.cc +++ b/webcc/request_parser.cc @@ -4,8 +4,9 @@ #include "boost/algorithm/string.hpp" -#include "webcc/request.h" #include "webcc/logger.h" +#include "webcc/request.h" +#include "webcc/utility.h" namespace webcc { diff --git a/webcc/request_parser.h b/webcc/request_parser.h index 93d1fc2..9c1e685 100644 --- a/webcc/request_parser.h +++ b/webcc/request_parser.h @@ -18,10 +18,10 @@ public: void Init(Request* request); private: - bool ParseStartLine(const std::string& line) final; + bool ParseStartLine(const std::string& line) override; // Override to handle multipart form data which is request only. - bool ParseContent(const char* data, std::size_t length) final; + bool ParseContent(const char* data, std::size_t length) override; // Multipart specific parsing helpers. diff --git a/webcc/response.h b/webcc/response.h index 9b4345e..861e97c 100644 --- a/webcc/response.h +++ b/webcc/response.h @@ -28,7 +28,7 @@ public: } // Set start line according to status code. - void Prepare() final; + void Prepare() override; private: int status_; diff --git a/webcc/response_parser.cc b/webcc/response_parser.cc index 31246a6..76e4e64 100644 --- a/webcc/response_parser.cc +++ b/webcc/response_parser.cc @@ -16,6 +16,7 @@ void ResponseParser::Init(Response* response) { response_ = response; } +// TODO: Keep the original message. bool ResponseParser::ParseStartLine(const std::string& line) { std::vector parts; boost::split(parts, line, boost::is_any_of(" "), boost::token_compress_on); diff --git a/webcc/response_parser.h b/webcc/response_parser.h index 83717f5..57f98bd 100644 --- a/webcc/response_parser.h +++ b/webcc/response_parser.h @@ -19,7 +19,7 @@ public: private: // Parse HTTP start line; E.g., "HTTP/1.1 200 OK". - bool ParseStartLine(const std::string& line) final; + bool ParseStartLine(const std::string& line) override; // The result response message. Response* response_; diff --git a/webcc/rest_request_handler.h b/webcc/rest_request_handler.h index 40b9993..5291c74 100644 --- a/webcc/rest_request_handler.h +++ b/webcc/rest_request_handler.h @@ -19,7 +19,7 @@ public: bool Bind(RestServicePtr service, const std::string& url, bool is_regex); private: - void HandleConnection(ConnectionPtr connection) final; + void HandleConnection(ConnectionPtr connection) override; void SetContent(RequestPtr request, ResponsePtr response, std::string&& content); diff --git a/webcc/rest_server.h b/webcc/rest_server.h index 3111d85..91321a8 100644 --- a/webcc/rest_server.h +++ b/webcc/rest_server.h @@ -32,7 +32,7 @@ public: } private: - RequestHandler* GetRequestHandler() final { + RequestHandler* GetRequestHandler() override { return &request_handler_; } diff --git a/webcc/socket.h b/webcc/socket.h index da80cd7..2d6f3ec 100644 --- a/webcc/socket.h +++ b/webcc/socket.h @@ -47,14 +47,14 @@ public: void Connect(const std::string& host, const Endpoints& endpoints, - boost::system::error_code* ec) final; + boost::system::error_code* ec) override; void Write(const Request& request, - boost::system::error_code* ec) final; + boost::system::error_code* ec) override; - void AsyncReadSome(ReadHandler&& handler, std::vector* buffer) final; + void AsyncReadSome(ReadHandler&& handler, std::vector* buffer) override; - void Close(boost::system::error_code* ec) final; + void Close(boost::system::error_code* ec) override; private: boost::asio::ip::tcp::socket socket_; @@ -71,14 +71,14 @@ public: void Connect(const std::string& host, const Endpoints& endpoints, - boost::system::error_code* ec) final; + boost::system::error_code* ec) override; void Write(const Request& request, - boost::system::error_code* ec) final; + boost::system::error_code* ec) override; - void AsyncReadSome(ReadHandler&& handler, std::vector* buffer) final; + void AsyncReadSome(ReadHandler&& handler, std::vector* buffer) override; - void Close(boost::system::error_code* ec) final; + void Close(boost::system::error_code* ec) override; private: void Handshake(const std::string& host, boost::system::error_code* ec); diff --git a/webcc/utility.cc b/webcc/utility.cc index 99580d6..a172a21 100644 --- a/webcc/utility.cc +++ b/webcc/utility.cc @@ -2,6 +2,7 @@ #include +#include "boost/algorithm/string.hpp" #include "boost/uuid/random_generator.hpp" #include "boost/uuid/uuid_io.hpp" @@ -14,4 +15,20 @@ std::string RandomUuid() { return ss.str(); } +bool Split2(const std::string& str, char token, std::string* part1, + std::string* part2) { + std::size_t pos = str.find(token); + if (pos == std::string::npos) { + return false; + } + + *part1 = str.substr(0, pos); + *part2 = str.substr(pos + 1); + + boost::trim(*part1); + boost::trim(*part2); + + return true; +} + } // namespace webcc diff --git a/webcc/utility.h b/webcc/utility.h index f4e6fcc..2b06d68 100644 --- a/webcc/utility.h +++ b/webcc/utility.h @@ -7,6 +7,10 @@ namespace webcc { std::string RandomUuid(); +// Split a string to two parts by the given token. +bool Split2(const std::string& str, char token, std::string* part1, + std::string* part2); + } // namespace webcc #endif // WEBCC_UTILITY_H_