Refine files upload.
This commit is contained in:
@@ -103,34 +103,6 @@ void ExampleImage(const std::string& path) {
|
|||||||
ofs << r->content();
|
ofs << r->content();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post/upload files.
|
|
||||||
void ExamplePostFiles() {
|
|
||||||
webcc::HttpClientSession session;
|
|
||||||
|
|
||||||
auto r = session.Request(webcc::HttpRequestBuilder{}
|
|
||||||
.Post()
|
|
||||||
.Url("http://httpbin.org/post")
|
|
||||||
.FileData("file1", "report.xls", "<xls report data>", "application/vnd.ms-excel")
|
|
||||||
.FileData("file2", "report.xml", "<xml report data>", "text/xml")());
|
|
||||||
|
|
||||||
std::cout << r->content() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Post/upload files by file path.
|
|
||||||
void ExamplePostFiles(const std::string& url,
|
|
||||||
const std::string& name,
|
|
||||||
const std::string& file_name,
|
|
||||||
const std::string& file_path,
|
|
||||||
const std::string& content_type) {
|
|
||||||
webcc::HttpClientSession session;
|
|
||||||
|
|
||||||
auto r = session.Request(webcc::HttpRequestBuilder{}.Post().
|
|
||||||
Url(url).
|
|
||||||
File(name, file_name, file_path, content_type)());
|
|
||||||
|
|
||||||
std::cout << r->content() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
WEBCC_LOG_INIT("", webcc::LOG_CONSOLE);
|
WEBCC_LOG_INIT("", webcc::LOG_CONSOLE);
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ set(HEADERS
|
|||||||
http_client_session.h
|
http_client_session.h
|
||||||
http_connection.h
|
http_connection.h
|
||||||
http_connection_pool.h
|
http_connection_pool.h
|
||||||
|
http_file.h
|
||||||
http_message.h
|
http_message.h
|
||||||
http_parser.h
|
http_parser.h
|
||||||
http_request.h
|
http_request.h
|
||||||
@@ -50,6 +51,7 @@ set(SOURCES
|
|||||||
http_client_session.cc
|
http_client_session.cc
|
||||||
http_connection.cc
|
http_connection.cc
|
||||||
http_connection_pool.cc
|
http_connection_pool.cc
|
||||||
|
http_file.cc
|
||||||
http_message.cc
|
http_message.cc
|
||||||
http_parser.cc
|
http_parser.cc
|
||||||
http_request.cc
|
http_request.cc
|
||||||
|
|||||||
+2
-43
@@ -1,33 +1,13 @@
|
|||||||
#include "webcc/globals.h"
|
#include "webcc/globals.h"
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "boost/filesystem/path.hpp"
|
|
||||||
|
|
||||||
#include "webcc/version.h"
|
#include "webcc/version.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Read entire file into string.
|
|
||||||
static bool ReadFile(const std::string& path, std::string* output) {
|
|
||||||
std::ifstream ifs{path, std::ios::binary | std::ios::ate};
|
|
||||||
if (!ifs) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto size = ifs.tellg();
|
|
||||||
output->resize((std::size_t)size, '\0');
|
|
||||||
ifs.seekg(0);
|
|
||||||
ifs.read(&(*output)[0], size); // TODO: Error handling
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
const std::string& UserAgent() {
|
const std::string& UserAgent() {
|
||||||
@@ -35,29 +15,6 @@ const std::string& UserAgent() {
|
|||||||
return s_user_agent;
|
return s_user_agent;
|
||||||
}
|
}
|
||||||
|
|
||||||
File::File(const std::string& file_path) {
|
|
||||||
if (!ReadFile(file_path, &data)) {
|
|
||||||
throw Exception(kFileIOError, "Cannot read the file.");
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace bfs = boost::filesystem;
|
|
||||||
|
|
||||||
// Determine file name from file path.
|
|
||||||
//if (file_name.empty()) {
|
|
||||||
file_name = bfs::path(file_path).filename().string();
|
|
||||||
//} else {
|
|
||||||
// file_name = file_name;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Determine content type from file extension.
|
|
||||||
//if (mime_type.empty()) {
|
|
||||||
std::string extension = bfs::path(file_path).extension().string();
|
|
||||||
mime_type = http::media_types::FromExtension(extension, false);
|
|
||||||
//} else {
|
|
||||||
//mime_type = mime_type;
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace media_types {
|
namespace media_types {
|
||||||
|
|
||||||
// TODO: Add more.
|
// TODO: Add more.
|
||||||
@@ -97,6 +54,8 @@ std::string FromExtension(const std::string& extension,
|
|||||||
|
|
||||||
} // namespace http
|
} // namespace http
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
const char* DescribeError(Error error) {
|
const char* DescribeError(Error error) {
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case kSchemaError:
|
case kSchemaError:
|
||||||
|
|||||||
@@ -154,24 +154,6 @@ enum class ContentEncoding {
|
|||||||
// Return default user agent for HTTP headers.
|
// Return default user agent for HTTP headers.
|
||||||
const std::string& UserAgent();
|
const std::string& UserAgent();
|
||||||
|
|
||||||
// File for HTTP transfer (upload/download).
|
|
||||||
class File {
|
|
||||||
public:
|
|
||||||
File() = default;
|
|
||||||
|
|
||||||
File(const std::string& file_path);
|
|
||||||
|
|
||||||
// Binary file data.
|
|
||||||
// TODO: don't use std::string?
|
|
||||||
std::string data;
|
|
||||||
|
|
||||||
// E.g., example.jpg
|
|
||||||
std::string file_name;
|
|
||||||
|
|
||||||
// E.g., image/jpeg
|
|
||||||
std::string mime_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace http
|
} // namespace http
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -5,11 +5,13 @@
|
|||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
HttpClientPool::~HttpClientPool() {
|
HttpClientPool::~HttpClientPool() {
|
||||||
LOG_INFO("Close socket for all (%u) connections in the pool.",
|
if (!clients_.empty()) {
|
||||||
clients_.size());
|
LOG_INFO("Close socket for all (%u) connections in the pool.",
|
||||||
|
clients_.size());
|
||||||
|
|
||||||
for (auto& pair : clients_) {
|
for (auto& pair : clients_) {
|
||||||
pair.second->Close();
|
pair.second->Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ static void SetHeaders(const std::vector<std::string>& headers,
|
|||||||
HttpResponsePtr HttpClientSession::Get(
|
HttpResponsePtr HttpClientSession::Get(
|
||||||
const std::string& url, const std::vector<std::string>& parameters,
|
const std::string& url, const std::vector<std::string>& parameters,
|
||||||
const std::vector<std::string>& headers) {
|
const std::vector<std::string>& headers) {
|
||||||
HttpRequestBuilder builder{http::methods::kGet};
|
HttpRequestBuilder builder;
|
||||||
builder.Url(url);
|
builder.Get().Url(url);
|
||||||
|
|
||||||
assert(parameters.size() % 2 == 0);
|
assert(parameters.size() % 2 == 0);
|
||||||
for (std::size_t i = 1; i < parameters.size(); i += 2) {
|
for (std::size_t i = 1; i < parameters.size(); i += 2) {
|
||||||
@@ -56,8 +56,8 @@ HttpResponsePtr HttpClientSession::Get(
|
|||||||
HttpResponsePtr HttpClientSession::Post(
|
HttpResponsePtr HttpClientSession::Post(
|
||||||
const std::string& url, std::string&& data, bool json,
|
const std::string& url, std::string&& data, bool json,
|
||||||
const std::vector<std::string>& headers) {
|
const std::vector<std::string>& headers) {
|
||||||
HttpRequestBuilder builder{http::methods::kPost};
|
HttpRequestBuilder builder;
|
||||||
builder.Url(url);
|
builder.Post().Url(url);
|
||||||
|
|
||||||
SetHeaders(headers, &builder);
|
SetHeaders(headers, &builder);
|
||||||
|
|
||||||
@@ -67,16 +67,32 @@ HttpResponsePtr HttpClientSession::Post(
|
|||||||
return Request(builder());
|
return Request(builder());
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponsePtr HttpClientSession::PostFile(const std::string& url,
|
HttpResponsePtr HttpClientSession::PostFile(
|
||||||
const std::string& name,
|
const std::string& url, const std::string& name, const Path& path,
|
||||||
http::File&& file,
|
const std::vector<std::string>& headers) {
|
||||||
const std::vector<std::string>& headers) {
|
HttpRequestBuilder builder;
|
||||||
HttpRequestBuilder builder{http::methods::kPost};
|
builder.Post().Url(url);
|
||||||
builder.Url(url);
|
|
||||||
|
|
||||||
SetHeaders(headers, &builder);
|
SetHeaders(headers, &builder);
|
||||||
|
|
||||||
builder.File(name, std::move(file));
|
builder.File(name, path);
|
||||||
|
|
||||||
|
return Request(builder());
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponsePtr HttpClientSession::PostFiles(
|
||||||
|
const std::string& url, const std::map<std::string, Path>& paths,
|
||||||
|
const std::vector<std::string>& headers) {
|
||||||
|
assert(!paths.empty());
|
||||||
|
|
||||||
|
HttpRequestBuilder builder;
|
||||||
|
builder.Post().Url(url);
|
||||||
|
|
||||||
|
SetHeaders(headers, &builder);
|
||||||
|
|
||||||
|
for (auto& pair : paths) {
|
||||||
|
builder.File(pair.first, pair.second);
|
||||||
|
}
|
||||||
|
|
||||||
return Request(builder());
|
return Request(builder());
|
||||||
}
|
}
|
||||||
@@ -84,8 +100,8 @@ HttpResponsePtr HttpClientSession::PostFile(const std::string& url,
|
|||||||
HttpResponsePtr HttpClientSession::Put(
|
HttpResponsePtr HttpClientSession::Put(
|
||||||
const std::string& url, std::string&& data, bool json,
|
const std::string& url, std::string&& data, bool json,
|
||||||
const std::vector<std::string>& headers) {
|
const std::vector<std::string>& headers) {
|
||||||
HttpRequestBuilder builder{http::methods::kPut};
|
HttpRequestBuilder builder;
|
||||||
builder.Url(url);
|
builder.Put().Url(url);
|
||||||
|
|
||||||
SetHeaders(headers, &builder);
|
SetHeaders(headers, &builder);
|
||||||
|
|
||||||
@@ -97,8 +113,8 @@ HttpResponsePtr HttpClientSession::Put(
|
|||||||
|
|
||||||
HttpResponsePtr HttpClientSession::Delete(
|
HttpResponsePtr HttpClientSession::Delete(
|
||||||
const std::string& url, const std::vector<std::string>& headers) {
|
const std::string& url, const std::vector<std::string>& headers) {
|
||||||
HttpRequestBuilder builder{http::methods::kDelete};
|
HttpRequestBuilder builder;
|
||||||
builder.Url(url);
|
builder.Delete().Url(url);
|
||||||
|
|
||||||
SetHeaders(headers, &builder);
|
SetHeaders(headers, &builder);
|
||||||
|
|
||||||
@@ -108,8 +124,8 @@ HttpResponsePtr HttpClientSession::Delete(
|
|||||||
HttpResponsePtr HttpClientSession::Patch(
|
HttpResponsePtr HttpClientSession::Patch(
|
||||||
const std::string& url, std::string&& data, bool json,
|
const std::string& url, std::string&& data, bool json,
|
||||||
const std::vector<std::string>& headers) {
|
const std::vector<std::string>& headers) {
|
||||||
HttpRequestBuilder builder{http::methods::kPatch};
|
HttpRequestBuilder builder;
|
||||||
builder.Url(url);
|
builder.Patch().Url(url);
|
||||||
|
|
||||||
SetHeaders(headers, &builder);
|
SetHeaders(headers, &builder);
|
||||||
|
|
||||||
|
|||||||
@@ -60,11 +60,15 @@ public:
|
|||||||
const std::vector<std::string>& headers = {});
|
const std::vector<std::string>& headers = {});
|
||||||
|
|
||||||
// Post a file.
|
// Post a file.
|
||||||
HttpResponsePtr PostFile(const std::string& url,
|
HttpResponsePtr PostFile(const std::string& url, const std::string& name,
|
||||||
const std::string& name,
|
const Path& path,
|
||||||
http::File&& file,
|
|
||||||
const std::vector<std::string>& headers = {});
|
const std::vector<std::string>& headers = {});
|
||||||
|
|
||||||
|
// Post multiple files.
|
||||||
|
HttpResponsePtr PostFiles(const std::string& url,
|
||||||
|
const std::map<std::string, Path>& paths,
|
||||||
|
const std::vector<std::string>& headers = {});
|
||||||
|
|
||||||
// Shortcut for PUT request.
|
// Shortcut for PUT request.
|
||||||
HttpResponsePtr Put(const std::string& url, std::string&& data, bool json,
|
HttpResponsePtr Put(const std::string& url, std::string&& data, bool json,
|
||||||
const std::vector<std::string>& headers = {});
|
const std::vector<std::string>& headers = {});
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#include "webcc/http_file.h"
|
||||||
|
|
||||||
|
#include "boost/filesystem/fstream.hpp"
|
||||||
|
|
||||||
|
namespace bfs = boost::filesystem;
|
||||||
|
|
||||||
|
namespace webcc {
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Read entire file into string.
|
||||||
|
static 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');
|
||||||
|
ifs.seekg(0);
|
||||||
|
ifs.read(&(*output)[0], size); // TODO: Error handling
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HttpFile::HttpFile(const Path& path, const std::string& mime_type) {
|
||||||
|
if (!ReadFile(path, &data_)) {
|
||||||
|
throw Exception(kFileIOError, "Cannot read the file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine file name from file path.
|
||||||
|
// TODO: Encoding
|
||||||
|
file_name_ = path.filename().string();
|
||||||
|
|
||||||
|
// Determine content type from file extension.
|
||||||
|
if (mime_type.empty()) {
|
||||||
|
std::string extension = path.extension().string();
|
||||||
|
mime_type_ = http::media_types::FromExtension(extension, false);
|
||||||
|
} else {
|
||||||
|
mime_type_ = mime_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpFile::HttpFile(std::string&& data, const std::string& file_name,
|
||||||
|
const std::string& mime_type) {
|
||||||
|
data_ = std::move(data);
|
||||||
|
|
||||||
|
file_name_ = file_name;
|
||||||
|
|
||||||
|
mime_type_ = mime_type;
|
||||||
|
|
||||||
|
// Determine content type from file extension.
|
||||||
|
if (mime_type_.empty()) {
|
||||||
|
std::size_t pos = file_name_.find_last_of('.');
|
||||||
|
if (pos != std::string::npos) {
|
||||||
|
std::string extension = file_name_.substr(pos + 1);
|
||||||
|
mime_type_ = http::media_types::FromExtension(extension, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webcc
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#ifndef WEBCC_HTTP_FILE_H_
|
||||||
|
#define WEBCC_HTTP_FILE_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "boost/filesystem/path.hpp"
|
||||||
|
|
||||||
|
#include "webcc/globals.h"
|
||||||
|
|
||||||
|
namespace webcc {
|
||||||
|
|
||||||
|
using Path = boost::filesystem::path;
|
||||||
|
|
||||||
|
// File for HTTP transfer (upload/download).
|
||||||
|
class HttpFile {
|
||||||
|
public:
|
||||||
|
HttpFile() = default;
|
||||||
|
|
||||||
|
explicit HttpFile(const Path& path, const std::string& mime_type = "");
|
||||||
|
|
||||||
|
HttpFile(std::string&& data, const std::string& file_name,
|
||||||
|
const std::string& mime_type = "");
|
||||||
|
|
||||||
|
#if WEBCC_DEFAULT_MOVE_COPY_ASSIGN
|
||||||
|
|
||||||
|
HttpFile(HttpFile&&) = default;
|
||||||
|
HttpFile& operator=(HttpFile&&) = default;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
HttpFile(HttpFile&& rhs)
|
||||||
|
: data_(std::move(rhs.data_)),
|
||||||
|
file_name_(std::move(rhs.file_name_)),
|
||||||
|
mime_type_(std::move(rhs.mime_type_)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpFile& operator=(HttpFile&& rhs) {
|
||||||
|
if (&rhs != this) {
|
||||||
|
data_ = std::move(rhs.data_);
|
||||||
|
file_name_ = std::move(rhs.file_name_);
|
||||||
|
mime_type_ = std::move(rhs.mime_type_);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WEBCC_DEFAULT_MOVE_COPY_ASSIGN
|
||||||
|
|
||||||
|
const std::string& data() const {
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& file_name() const {
|
||||||
|
return file_name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& mime_type() const {
|
||||||
|
return mime_type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Binary file data.
|
||||||
|
// TODO: don't use std::string?
|
||||||
|
std::string data_;
|
||||||
|
|
||||||
|
// E.g., example.jpg
|
||||||
|
// TODO: Unicode
|
||||||
|
std::string file_name_;
|
||||||
|
|
||||||
|
// E.g., image/jpeg
|
||||||
|
std::string mime_type_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webcc
|
||||||
|
|
||||||
|
#endif // WEBCC_HTTP_FILE_H_
|
||||||
@@ -51,33 +51,22 @@ HttpRequestPtr HttpRequestBuilder::Build() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HttpRequestBuilder& HttpRequestBuilder::File(const std::string& name,
|
HttpRequestBuilder& HttpRequestBuilder::File(const std::string& name,
|
||||||
const std::string& file_path,
|
const Path& path,
|
||||||
const std::string& file_name,
|
|
||||||
const std::string& mime_type) {
|
const std::string& mime_type) {
|
||||||
assert(!name.empty());
|
assert(!name.empty());
|
||||||
|
|
||||||
// TODO
|
files_[name] = HttpFile(path, mime_type);
|
||||||
files_[name] = http::File(file_path/*, file_name, mime_type*/);
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpRequestBuilder& HttpRequestBuilder::File(const std::string& name,
|
|
||||||
http::File&& file) {
|
|
||||||
files_[name] = std::move(file);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpRequestBuilder& HttpRequestBuilder::FileData(const std::string& name,
|
HttpRequestBuilder& HttpRequestBuilder::FileData(const std::string& name,
|
||||||
std::string&& file_data,
|
std::string&& file_data,
|
||||||
const std::string& file_name,
|
const std::string& file_name,
|
||||||
const std::string& mime_type) {
|
const std::string& mime_type) {
|
||||||
http::File file;
|
assert(!name.empty());
|
||||||
file.data = std::move(file_data);
|
|
||||||
file.file_name = file_name;
|
|
||||||
file.mime_type = mime_type;
|
|
||||||
|
|
||||||
files_[name] = std::move(file);
|
files_[name] = HttpFile(std::move(file_data), file_name, mime_type);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -121,21 +110,21 @@ void HttpRequestBuilder::CreateFormData(std::string* data,
|
|||||||
if (!pair.first.empty()) {
|
if (!pair.first.empty()) {
|
||||||
data->append("; name=\"" + pair.first + "\"");
|
data->append("; name=\"" + pair.first + "\"");
|
||||||
}
|
}
|
||||||
if (!pair.second.file_name.empty()) {
|
if (!pair.second.file_name().empty()) {
|
||||||
data->append("; filename=\"" + pair.second.file_name + "\"");
|
data->append("; filename=\"" + pair.second.file_name() + "\"");
|
||||||
}
|
}
|
||||||
data->append(kCRLF);
|
data->append(kCRLF);
|
||||||
|
|
||||||
// Content-Type header
|
// Content-Type header
|
||||||
if (!pair.second.mime_type.empty()) {
|
if (!pair.second.mime_type().empty()) {
|
||||||
data->append("Content-Type: " + pair.second.mime_type);
|
data->append("Content-Type: " + pair.second.mime_type());
|
||||||
data->append(kCRLF);
|
data->append(kCRLF);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->append(kCRLF);
|
data->append(kCRLF);
|
||||||
|
|
||||||
// Payload
|
// Payload
|
||||||
data->append(pair.second.data);
|
data->append(pair.second.data());
|
||||||
|
|
||||||
data->append(kCRLF);
|
data->append(kCRLF);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "webcc/http_file.h"
|
||||||
#include "webcc/http_request.h"
|
#include "webcc/http_request.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
@@ -66,15 +67,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Upload a file with its path.
|
// Upload a file with its path.
|
||||||
// TODO: UNICODE file path.
|
HttpRequestBuilder& File(const std::string& name, const Path& path,
|
||||||
HttpRequestBuilder& File(const std::string& name,
|
|
||||||
const std::string& file_path,
|
|
||||||
const std::string& file_name = "",
|
|
||||||
const std::string& mime_type = "");
|
const std::string& mime_type = "");
|
||||||
|
|
||||||
HttpRequestBuilder& File(const std::string& name, http::File&& file);
|
HttpRequestBuilder& File(const std::string& name, HttpFile&& file) {
|
||||||
|
files_[name] = std::move(file);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// Upload a file with its data.
|
// Upload a file with its data.
|
||||||
|
// TODO: Unicode |file_name|.
|
||||||
HttpRequestBuilder& FileData(const std::string& name,
|
HttpRequestBuilder& FileData(const std::string& name,
|
||||||
std::string&& file_data,
|
std::string&& file_data,
|
||||||
const std::string& file_name = "",
|
const std::string& file_name = "",
|
||||||
@@ -122,8 +124,8 @@ private:
|
|||||||
// Is the data to send a JSON string?
|
// Is the data to send a JSON string?
|
||||||
bool json_ = false;
|
bool json_ = false;
|
||||||
|
|
||||||
// Files to upload for a POST (or PUT?) request.
|
// Files to upload for a POST request.
|
||||||
std::map<std::string, http::File> files_;
|
std::map<std::string, HttpFile> files_;
|
||||||
|
|
||||||
// Compress the request content.
|
// Compress the request content.
|
||||||
// NOTE: Most servers don't support compressed requests.
|
// NOTE: Most servers don't support compressed requests.
|
||||||
|
|||||||
Reference in New Issue
Block a user