Remove PostFile() from session; refine cmake files; replace final with override.
This commit is contained in:
@@ -7,7 +7,7 @@ set(AT_SRCS
|
|||||||
set(AT_TARGET_NAME webcc_autotest)
|
set(AT_TARGET_NAME webcc_autotest)
|
||||||
|
|
||||||
# Common libraries to link.
|
# 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)
|
if(WEBCC_ENABLE_SSL)
|
||||||
set(AT_LIBS ${AT_LIBS} ${OPENSSL_LIBRARIES})
|
set(AT_LIBS ${AT_LIBS} ${OPENSSL_LIBRARIES})
|
||||||
@@ -31,4 +31,4 @@ if(UNIX)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(${AT_TARGET_NAME} ${AT_SRCS})
|
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})
|
||||||
|
|||||||
@@ -50,15 +50,13 @@ int main(int argc, char* argv[]) {
|
|||||||
webcc::ClientSession session;
|
webcc::ClientSession session;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//auto r = session.PostFile(url, "file", upload_dir / "remember.txt");
|
|
||||||
|
|
||||||
auto r = session.Request(webcc::RequestBuilder{}.Post().
|
auto r = session.Request(webcc::RequestBuilder{}.Post().
|
||||||
Url(url).
|
Url(url).
|
||||||
File("file", upload_dir / "remember.txt").
|
File("file", upload_dir / "remember.txt").
|
||||||
Form("json", "{}", "application/json")
|
Form("json", "{}", "application/json")
|
||||||
());
|
());
|
||||||
|
|
||||||
//std::cout << r->content() << std::endl;
|
std::cout << r->status() << std::endl;
|
||||||
|
|
||||||
} catch (const webcc::Exception& e) {
|
} catch (const webcc::Exception& e) {
|
||||||
std::cout << "Exception: " << e.what() << std::endl;
|
std::cout << "Exception: " << e.what() << std::endl;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
class FileUploadService : public webcc::RestService {
|
class FileUploadService : public webcc::RestService {
|
||||||
public:
|
public:
|
||||||
void Handle(const webcc::RestRequest& request,
|
void Handle(const webcc::RestRequest& request,
|
||||||
webcc::RestResponse* response) final {
|
webcc::RestResponse* response) override {
|
||||||
if (request.http->method() == "POST") {
|
if (request.http->method() == "POST") {
|
||||||
std::cout << "files: " << request.http->form_parts().size() << std::endl;
|
std::cout << "files: " << request.http->form_parts().size() << std::endl;
|
||||||
|
|
||||||
|
|||||||
@@ -42,11 +42,11 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Get a list of books based on query parameters.
|
// 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.
|
// Create a new book.
|
||||||
void Post(const std::string& request_content,
|
void Post(const std::string& request_content,
|
||||||
webcc::RestResponse* response) final;
|
webcc::RestResponse* response) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Sleep some seconds before send back the response.
|
// Sleep some seconds before send back the response.
|
||||||
@@ -68,16 +68,16 @@ protected:
|
|||||||
// Get the detailed information of a book.
|
// Get the detailed information of a book.
|
||||||
void Get(const webcc::UrlMatches& url_matches,
|
void Get(const webcc::UrlMatches& url_matches,
|
||||||
const webcc::UrlQuery& query,
|
const webcc::UrlQuery& query,
|
||||||
webcc::RestResponse* response) final;
|
webcc::RestResponse* response) override;
|
||||||
|
|
||||||
// Update a book.
|
// Update a book.
|
||||||
void Put(const webcc::UrlMatches& url_matches,
|
void Put(const webcc::UrlMatches& url_matches,
|
||||||
const std::string& request_content,
|
const std::string& request_content,
|
||||||
webcc::RestResponse* response) final;
|
webcc::RestResponse* response) override;
|
||||||
|
|
||||||
// Delete a book.
|
// Delete a book.
|
||||||
void Delete(const webcc::UrlMatches& url_matches,
|
void Delete(const webcc::UrlMatches& url_matches,
|
||||||
webcc::RestResponse* response) final;
|
webcc::RestResponse* response) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Sleep some seconds before send back the response.
|
// Sleep some seconds before send back the response.
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ set(UT_SRCS
|
|||||||
set(UT_TARGET_NAME webcc_unittest)
|
set(UT_TARGET_NAME webcc_unittest)
|
||||||
|
|
||||||
# Common libraries to link.
|
# 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)
|
if(WEBCC_ENABLE_SSL)
|
||||||
set(UT_LIBS ${UT_LIBS} ${OPENSSL_LIBRARIES})
|
set(UT_LIBS ${UT_LIBS} ${OPENSSL_LIBRARIES})
|
||||||
@@ -34,6 +34,6 @@ if(UNIX)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(${UT_TARGET_NAME} ${UT_SRCS})
|
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})
|
add_test(${UT_TARGET_NAME} ${UT_TARGET_NAME})
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
class MyRestService : public webcc::RestService {
|
class MyRestService : public webcc::RestService {
|
||||||
public:
|
public:
|
||||||
void Handle(const webcc::RestRequest& request,
|
void Handle(const webcc::RestRequest& request,
|
||||||
webcc::RestResponse* response) final {
|
webcc::RestResponse* response) override {
|
||||||
response->status = webcc::Status::kOK;
|
response->status = webcc::Status::kOK;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -121,36 +121,6 @@ ResponsePtr ClientSession::Patch(const std::string& url, std::string&& data,
|
|||||||
return Request(builder());
|
return Request(builder());
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponsePtr ClientSession::PostFile(const std::string& url,
|
|
||||||
const std::string& name, const Path& path,
|
|
||||||
const std::vector<std::string>& 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<std::string, Path>& paths,
|
|
||||||
const std::vector<std::string>& 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() {
|
void ClientSession::InitHeaders() {
|
||||||
using namespace headers;
|
using namespace headers;
|
||||||
|
|
||||||
|
|||||||
@@ -79,16 +79,6 @@ public:
|
|||||||
ResponsePtr Patch(const std::string& url, std::string&& data, bool json,
|
ResponsePtr Patch(const std::string& url, std::string&& data, bool json,
|
||||||
const std::vector<std::string>& headers = {});
|
const std::vector<std::string>& headers = {});
|
||||||
|
|
||||||
// Post a file.
|
|
||||||
ResponsePtr PostFile(const std::string& url, const std::string& name,
|
|
||||||
const Path& path,
|
|
||||||
const std::vector<std::string>& headers = {});
|
|
||||||
|
|
||||||
// Post multiple files.
|
|
||||||
ResponsePtr PostFiles(const std::string& url,
|
|
||||||
const std::map<std::string, Path>& paths,
|
|
||||||
const std::vector<std::string>& headers = {});
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitHeaders();
|
void InitHeaders();
|
||||||
|
|
||||||
|
|||||||
+12
-23
@@ -6,6 +6,7 @@
|
|||||||
#include "boost/filesystem/fstream.hpp"
|
#include "boost/filesystem/fstream.hpp"
|
||||||
|
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
|
#include "webcc/utility.h"
|
||||||
|
|
||||||
namespace bfs = boost::filesystem;
|
namespace bfs = boost::filesystem;
|
||||||
|
|
||||||
@@ -24,33 +25,21 @@ const char CRLF[] = { '\r', '\n' };
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool Split2(const std::string& str, char token, std::string* part1,
|
// Read entire file into string.
|
||||||
std::string* part2) {
|
static bool ReadFile(const Path& path, std::string* output) {
|
||||||
std::size_t pos = str.find(token);
|
// Flag "ate": seek to the end of stream immediately after open.
|
||||||
if (pos == std::string::npos) {
|
bfs::ifstream stream{ path, std::ios::binary | std::ios::ate };
|
||||||
|
if (stream.fail()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*part1 = str.substr(0, pos);
|
auto size = stream.tellg();
|
||||||
*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) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto size = ifs.tellg();
|
|
||||||
output->resize(static_cast<std::size_t>(size), '\0');
|
output->resize(static_cast<std::size_t>(size), '\0');
|
||||||
ifs.seekg(0);
|
stream.seekg(std::ios::beg);
|
||||||
ifs.read(&(*output)[0], size); // TODO: Error handling
|
stream.read(&(*output)[0], size);
|
||||||
|
if (stream.fail()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,15 +21,6 @@ using Payload = std::vector<boost::asio::const_buffer>;
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// 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<std::string, std::string>;
|
using Header = std::pair<std::string, std::string>;
|
||||||
|
|
||||||
class Headers {
|
class Headers {
|
||||||
|
|||||||
+1
-1
@@ -68,7 +68,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prepare payload.
|
// Prepare payload.
|
||||||
void Prepare() final;
|
void Prepare() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateStartLine();
|
void CreateStartLine();
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
|
|
||||||
#include "boost/algorithm/string.hpp"
|
#include "boost/algorithm/string.hpp"
|
||||||
|
|
||||||
#include "webcc/request.h"
|
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
|
#include "webcc/request.h"
|
||||||
|
#include "webcc/utility.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ public:
|
|||||||
void Init(Request* request);
|
void Init(Request* request);
|
||||||
|
|
||||||
private:
|
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.
|
// 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.
|
// Multipart specific parsing helpers.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set start line according to status code.
|
// Set start line according to status code.
|
||||||
void Prepare() final;
|
void Prepare() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int status_;
|
int status_;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ void ResponseParser::Init(Response* response) {
|
|||||||
response_ = response;
|
response_ = response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Keep the original message.
|
||||||
bool ResponseParser::ParseStartLine(const std::string& line) {
|
bool ResponseParser::ParseStartLine(const std::string& line) {
|
||||||
std::vector<std::string> parts;
|
std::vector<std::string> parts;
|
||||||
boost::split(parts, line, boost::is_any_of(" "), boost::token_compress_on);
|
boost::split(parts, line, boost::is_any_of(" "), boost::token_compress_on);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Parse HTTP start line; E.g., "HTTP/1.1 200 OK".
|
// 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.
|
// The result response message.
|
||||||
Response* response_;
|
Response* response_;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public:
|
|||||||
bool Bind(RestServicePtr service, const std::string& url, bool is_regex);
|
bool Bind(RestServicePtr service, const std::string& url, bool is_regex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void HandleConnection(ConnectionPtr connection) final;
|
void HandleConnection(ConnectionPtr connection) override;
|
||||||
|
|
||||||
void SetContent(RequestPtr request, ResponsePtr response,
|
void SetContent(RequestPtr request, ResponsePtr response,
|
||||||
std::string&& content);
|
std::string&& content);
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RequestHandler* GetRequestHandler() final {
|
RequestHandler* GetRequestHandler() override {
|
||||||
return &request_handler_;
|
return &request_handler_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -47,14 +47,14 @@ public:
|
|||||||
|
|
||||||
void Connect(const std::string& host,
|
void Connect(const std::string& host,
|
||||||
const Endpoints& endpoints,
|
const Endpoints& endpoints,
|
||||||
boost::system::error_code* ec) final;
|
boost::system::error_code* ec) override;
|
||||||
|
|
||||||
void Write(const Request& request,
|
void Write(const Request& request,
|
||||||
boost::system::error_code* ec) final;
|
boost::system::error_code* ec) override;
|
||||||
|
|
||||||
void AsyncReadSome(ReadHandler&& handler, std::vector<char>* buffer) final;
|
void AsyncReadSome(ReadHandler&& handler, std::vector<char>* buffer) override;
|
||||||
|
|
||||||
void Close(boost::system::error_code* ec) final;
|
void Close(boost::system::error_code* ec) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::asio::ip::tcp::socket socket_;
|
boost::asio::ip::tcp::socket socket_;
|
||||||
@@ -71,14 +71,14 @@ public:
|
|||||||
|
|
||||||
void Connect(const std::string& host,
|
void Connect(const std::string& host,
|
||||||
const Endpoints& endpoints,
|
const Endpoints& endpoints,
|
||||||
boost::system::error_code* ec) final;
|
boost::system::error_code* ec) override;
|
||||||
|
|
||||||
void Write(const Request& request,
|
void Write(const Request& request,
|
||||||
boost::system::error_code* ec) final;
|
boost::system::error_code* ec) override;
|
||||||
|
|
||||||
void AsyncReadSome(ReadHandler&& handler, std::vector<char>* buffer) final;
|
void AsyncReadSome(ReadHandler&& handler, std::vector<char>* buffer) override;
|
||||||
|
|
||||||
void Close(boost::system::error_code* ec) final;
|
void Close(boost::system::error_code* ec) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Handshake(const std::string& host, boost::system::error_code* ec);
|
void Handshake(const std::string& host, boost::system::error_code* ec);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "boost/algorithm/string.hpp"
|
||||||
#include "boost/uuid/random_generator.hpp"
|
#include "boost/uuid/random_generator.hpp"
|
||||||
#include "boost/uuid/uuid_io.hpp"
|
#include "boost/uuid/uuid_io.hpp"
|
||||||
|
|
||||||
@@ -14,4 +15,20 @@ std::string RandomUuid() {
|
|||||||
return ss.str();
|
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
|
} // namespace webcc
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ namespace webcc {
|
|||||||
|
|
||||||
std::string RandomUuid();
|
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
|
} // namespace webcc
|
||||||
|
|
||||||
#endif // WEBCC_UTILITY_H_
|
#endif // WEBCC_UTILITY_H_
|
||||||
|
|||||||
Reference in New Issue
Block a user