don't use boost string algorithm
This commit is contained in:
@@ -13,10 +13,6 @@ set(AT_LIBS
|
|||||||
webcc
|
webcc
|
||||||
jsoncpp
|
jsoncpp
|
||||||
GTest::GTest
|
GTest::GTest
|
||||||
GTest::Main
|
|
||||||
Boost::filesystem
|
|
||||||
Boost::system
|
|
||||||
Boost::date_time
|
|
||||||
"${CMAKE_THREAD_LIBS_INIT}")
|
"${CMAKE_THREAD_LIBS_INIT}")
|
||||||
|
|
||||||
if(WEBCC_ENABLE_SSL)
|
if(WEBCC_ENABLE_SSL)
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include "boost/algorithm/string.hpp"
|
|
||||||
|
|
||||||
#include "json/json.h"
|
#include "json/json.h"
|
||||||
|
|
||||||
#include "webcc/client_session.h"
|
#include "webcc/client_session.h"
|
||||||
@@ -314,7 +312,7 @@ TEST(ClientTest, Post) {
|
|||||||
static sfs::path GenerateTempFile(const std::string& data) {
|
static sfs::path GenerateTempFile(const std::string& data) {
|
||||||
try {
|
try {
|
||||||
sfs::path path =
|
sfs::path path =
|
||||||
sfs::temp_directory_path() / webcc::string::RandomString(10);
|
sfs::temp_directory_path() / webcc::random_string(10);
|
||||||
|
|
||||||
std::ofstream ofs;
|
std::ofstream ofs;
|
||||||
ofs.open(path, std::ios::binary);
|
ofs.open(path, std::ios::binary);
|
||||||
@@ -434,26 +432,24 @@ TEST(ClientTest, KeepAlive) {
|
|||||||
// Keep-Alive by default.
|
// Keep-Alive by default.
|
||||||
auto r = session.Send(webcc::RequestBuilder{}.Get(url)());
|
auto r = session.Send(webcc::RequestBuilder{}.Get(url)());
|
||||||
|
|
||||||
using boost::iequals;
|
EXPECT_TRUE(webcc::iequals(r->GetHeader("Connection"), "Keep-alive"));
|
||||||
|
|
||||||
EXPECT_TRUE(iequals(r->GetHeader("Connection"), "Keep-alive"));
|
|
||||||
|
|
||||||
// Close by setting Connection header directly.
|
// Close by setting Connection header directly.
|
||||||
r = session.Send(webcc::RequestBuilder{}.Get(url).
|
r = session.Send(webcc::RequestBuilder{}.Get(url).
|
||||||
Header("Connection", "Close")
|
Header("Connection", "Close")
|
||||||
());
|
());
|
||||||
|
|
||||||
EXPECT_TRUE(iequals(r->GetHeader("Connection"), "Close"));
|
EXPECT_TRUE(webcc::iequals(r->GetHeader("Connection"), "Close"));
|
||||||
|
|
||||||
// Close by using request builder.
|
// Close by using request builder.
|
||||||
r = session.Send(webcc::RequestBuilder{}.Get(url).KeepAlive(false)());
|
r = session.Send(webcc::RequestBuilder{}.Get(url).KeepAlive(false)());
|
||||||
|
|
||||||
EXPECT_TRUE(iequals(r->GetHeader("Connection"), "Close"));
|
EXPECT_TRUE(webcc::iequals(r->GetHeader("Connection"), "Close"));
|
||||||
|
|
||||||
// Keep-Alive explicitly by using request builder.
|
// Keep-Alive explicitly by using request builder.
|
||||||
r = session.Send(webcc::RequestBuilder{}.Get(url).KeepAlive(true)());
|
r = session.Send(webcc::RequestBuilder{}.Get(url).KeepAlive(true)());
|
||||||
|
|
||||||
EXPECT_TRUE(iequals(r->GetHeader("Connection"), "Keep-alive"));
|
EXPECT_TRUE(webcc::iequals(r->GetHeader("Connection"), "Keep-alive"));
|
||||||
|
|
||||||
} catch (const webcc::Error& error) {
|
} catch (const webcc::Error& error) {
|
||||||
std::cerr << error << std::endl;
|
std::cerr << error << std::endl;
|
||||||
|
|||||||
@@ -3,9 +3,6 @@
|
|||||||
# Common libraries to link for examples.
|
# Common libraries to link for examples.
|
||||||
set(EXAMPLE_LIBS
|
set(EXAMPLE_LIBS
|
||||||
webcc
|
webcc
|
||||||
Boost::filesystem
|
|
||||||
Boost::system
|
|
||||||
Boost::date_time
|
|
||||||
"${CMAKE_THREAD_LIBS_INIT}")
|
"${CMAKE_THREAD_LIBS_INIT}")
|
||||||
|
|
||||||
if(WEBCC_ENABLE_SSL)
|
if(WEBCC_ENABLE_SSL)
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "boost/algorithm/string/predicate.hpp"
|
|
||||||
#include "json/json.h"
|
#include "json/json.h"
|
||||||
|
|
||||||
|
#include "webcc/string.h"
|
||||||
|
|
||||||
#include "book_json.h"
|
#include "book_json.h"
|
||||||
|
|
||||||
BookClient::BookClient(const std::string& url, int timeout)
|
BookClient::BookClient(const std::string& url, int timeout)
|
||||||
@@ -179,7 +180,7 @@ bool BookClient::CheckPhoto(const std::filesystem::path& photo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto ext = photo.extension().string();
|
auto ext = photo.extension().string();
|
||||||
if (!boost::iequals(ext, ".jpg") && !boost::iequals(ext, ".jpeg")) {
|
if (!webcc::iequals(ext, ".jpg") && !webcc::iequals(ext, ".jpeg")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "boost/filesystem/path.hpp"
|
|
||||||
#include "json/json-forwards.h"
|
#include "json/json-forwards.h"
|
||||||
|
|
||||||
#include "webcc/client_session.h"
|
#include "webcc/client_session.h"
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "boost/filesystem/path.hpp"
|
|
||||||
|
|
||||||
struct Book {
|
struct Book {
|
||||||
std::string id;
|
std::string id;
|
||||||
std::string title;
|
std::string title;
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ set(UT_LIBS
|
|||||||
webcc
|
webcc
|
||||||
GTest::GTest
|
GTest::GTest
|
||||||
GTest::Main
|
GTest::Main
|
||||||
Boost::filesystem
|
|
||||||
Boost::system
|
|
||||||
Boost::date_time
|
|
||||||
"${CMAKE_THREAD_LIBS_INIT}")
|
"${CMAKE_THREAD_LIBS_INIT}")
|
||||||
|
|
||||||
if(WEBCC_ENABLE_SSL)
|
if(WEBCC_ENABLE_SSL)
|
||||||
|
|||||||
@@ -0,0 +1,170 @@
|
|||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "webcc/string.h"
|
||||||
|
|
||||||
|
TEST(StringTest, iequals) {
|
||||||
|
EXPECT_TRUE(webcc::iequals("", ""));
|
||||||
|
EXPECT_TRUE(webcc::iequals("abc", "abc"));
|
||||||
|
EXPECT_TRUE(webcc::iequals("ABC", "abc"));
|
||||||
|
EXPECT_TRUE(webcc::iequals("123", "123"));
|
||||||
|
|
||||||
|
EXPECT_FALSE(webcc::iequals("abc", "def"));
|
||||||
|
EXPECT_FALSE(webcc::iequals("abc", "abcdef"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(StringTest, starts_with) {
|
||||||
|
EXPECT_TRUE(webcc::starts_with("123", "1"));
|
||||||
|
EXPECT_TRUE(webcc::starts_with("123", "12"));
|
||||||
|
EXPECT_TRUE(webcc::starts_with("123", "123"));
|
||||||
|
EXPECT_TRUE(webcc::starts_with(" 123", " "));
|
||||||
|
|
||||||
|
EXPECT_FALSE(webcc::starts_with("123", ""));
|
||||||
|
EXPECT_FALSE(webcc::starts_with("123", "2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(StringTest, split) {
|
||||||
|
std::vector<std::string> parts;
|
||||||
|
webcc::split(parts, "GET /path/to HTTP/1.1");
|
||||||
|
|
||||||
|
EXPECT_EQ(3, parts.size());
|
||||||
|
EXPECT_EQ("GET", parts[0]);
|
||||||
|
EXPECT_EQ("/path/to", parts[1]);
|
||||||
|
EXPECT_EQ("HTTP/1.1", parts[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(StringTest, split_token_compress_off) {
|
||||||
|
std::string str = "one,two,,three,,";
|
||||||
|
std::vector<std::string> parts;
|
||||||
|
|
||||||
|
// Same as:
|
||||||
|
// boost::split(parts, str, boost::is_any_of(","),
|
||||||
|
// boost::token_compress_off);
|
||||||
|
|
||||||
|
webcc::split(parts, str, ',', false);
|
||||||
|
|
||||||
|
EXPECT_EQ(6, parts.size());
|
||||||
|
EXPECT_EQ("one", parts[0]);
|
||||||
|
EXPECT_EQ("two", parts[1]);
|
||||||
|
EXPECT_EQ("", parts[2]);
|
||||||
|
EXPECT_EQ("three", parts[3]);
|
||||||
|
EXPECT_EQ("", parts[4]);
|
||||||
|
EXPECT_EQ("", parts[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(StringTest, split_token_compress_on) {
|
||||||
|
std::string str = "one,two,,three,,";
|
||||||
|
std::vector<std::string> parts;
|
||||||
|
|
||||||
|
// Same as:
|
||||||
|
// boost::split(parts, str, boost::is_any_of(","),
|
||||||
|
// boost::token_compress_on);
|
||||||
|
webcc::split(parts, str, ',', true);
|
||||||
|
|
||||||
|
EXPECT_EQ(4, parts.size());
|
||||||
|
EXPECT_EQ("one", parts[0]);
|
||||||
|
EXPECT_EQ("two", parts[1]);
|
||||||
|
EXPECT_EQ("three", parts[2]);
|
||||||
|
EXPECT_EQ("", parts[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(StringTest, split_new_line) {
|
||||||
|
std::vector<std::string> lines;
|
||||||
|
webcc::split(lines, "line one\nline two\nline 3", '\n');
|
||||||
|
|
||||||
|
EXPECT_EQ(3, lines.size());
|
||||||
|
EXPECT_EQ("line one", lines[0]);
|
||||||
|
EXPECT_EQ("line two", lines[1]);
|
||||||
|
EXPECT_EQ("line 3", lines[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(UtilityTest, split_kv) {
|
||||||
|
const std::string str = "key=value";
|
||||||
|
|
||||||
|
std::string key;
|
||||||
|
std::string value;
|
||||||
|
bool ok = webcc::split_kv(key, value, str, '=');
|
||||||
|
|
||||||
|
EXPECT_EQ(true, ok);
|
||||||
|
EXPECT_EQ("key", key);
|
||||||
|
EXPECT_EQ("value", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(UtilityTest, split_kv_other_delim) {
|
||||||
|
const std::string str = "key:value";
|
||||||
|
|
||||||
|
std::string key;
|
||||||
|
std::string value;
|
||||||
|
bool ok = webcc::split_kv(key, value, str, ':');
|
||||||
|
|
||||||
|
EXPECT_TRUE(ok);
|
||||||
|
|
||||||
|
EXPECT_EQ("key", key);
|
||||||
|
EXPECT_EQ("value", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(UtilityTest, split_kv_spaces) {
|
||||||
|
const std::string str = " key = value ";
|
||||||
|
|
||||||
|
std::string key;
|
||||||
|
std::string value;
|
||||||
|
bool ok = webcc::split_kv(key, value, str, '=');
|
||||||
|
|
||||||
|
EXPECT_TRUE(ok);
|
||||||
|
|
||||||
|
EXPECT_EQ("key", key);
|
||||||
|
EXPECT_EQ("value", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(UtilityTest, split_kv_spaces_no_trim) {
|
||||||
|
const std::string str = " key = value ";
|
||||||
|
|
||||||
|
std::string key;
|
||||||
|
std::string value;
|
||||||
|
bool ok = webcc::split_kv(key, value, str, '=', false);
|
||||||
|
|
||||||
|
EXPECT_TRUE(ok);
|
||||||
|
|
||||||
|
EXPECT_EQ(" key ", key);
|
||||||
|
EXPECT_EQ(" value ", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(UtilityTest, split_kv_no_key) {
|
||||||
|
const std::string str = "=value";
|
||||||
|
|
||||||
|
std::string key;
|
||||||
|
std::string value;
|
||||||
|
bool ok = webcc::split_kv(key, value, str, '=');
|
||||||
|
|
||||||
|
EXPECT_TRUE(ok);
|
||||||
|
|
||||||
|
EXPECT_EQ("", key);
|
||||||
|
EXPECT_EQ("value", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(UtilityTest, split_kv_no_value) {
|
||||||
|
const std::string str = "key=";
|
||||||
|
|
||||||
|
std::string key;
|
||||||
|
std::string value;
|
||||||
|
bool ok = webcc::split_kv(key, value, str, '=');
|
||||||
|
|
||||||
|
EXPECT_TRUE(ok);
|
||||||
|
|
||||||
|
EXPECT_EQ("key", key);
|
||||||
|
EXPECT_EQ("", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(UtilityTest, split_kv_no_key_no_value) {
|
||||||
|
const std::string str = "=";
|
||||||
|
|
||||||
|
std::string key;
|
||||||
|
std::string value;
|
||||||
|
bool ok = webcc::split_kv(key, value, str, '=');
|
||||||
|
|
||||||
|
EXPECT_TRUE(ok);
|
||||||
|
|
||||||
|
EXPECT_EQ("", key);
|
||||||
|
EXPECT_EQ("", value);
|
||||||
|
}
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
#include "gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "webcc/utility.h"
|
|
||||||
|
|
||||||
TEST(UtilityTest, SplitKV) {
|
|
||||||
const std::string str = "key=value";
|
|
||||||
|
|
||||||
std::string key;
|
|
||||||
std::string value;
|
|
||||||
|
|
||||||
bool ok = webcc::utility::SplitKV(str, '=', &key, &value);
|
|
||||||
|
|
||||||
EXPECT_EQ(true, ok);
|
|
||||||
EXPECT_EQ("key", key);
|
|
||||||
EXPECT_EQ("value", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(UtilityTest, SplitKV_OtherDelim) {
|
|
||||||
const std::string str = "key:value";
|
|
||||||
|
|
||||||
std::string key;
|
|
||||||
std::string value;
|
|
||||||
|
|
||||||
bool ok = webcc::utility::SplitKV(str, ':', &key, &value);
|
|
||||||
EXPECT_TRUE(ok);
|
|
||||||
|
|
||||||
EXPECT_EQ("key", key);
|
|
||||||
EXPECT_EQ("value", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(UtilityTest, SplitKV_Spaces) {
|
|
||||||
const std::string str = " key = value ";
|
|
||||||
|
|
||||||
std::string key;
|
|
||||||
std::string value;
|
|
||||||
|
|
||||||
bool ok = webcc::utility::SplitKV(str, '=', &key, &value);
|
|
||||||
EXPECT_TRUE(ok);
|
|
||||||
|
|
||||||
EXPECT_EQ("key", key);
|
|
||||||
EXPECT_EQ("value", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(UtilityTest, SplitKV_SpacesNoTrim) {
|
|
||||||
const std::string str = " key = value ";
|
|
||||||
|
|
||||||
std::string key;
|
|
||||||
std::string value;
|
|
||||||
|
|
||||||
bool ok = webcc::utility::SplitKV(str, '=', &key, &value, false);
|
|
||||||
EXPECT_TRUE(ok);
|
|
||||||
|
|
||||||
EXPECT_EQ(" key ", key);
|
|
||||||
EXPECT_EQ(" value ", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(UtilityTest, SplitKV_NoKey) {
|
|
||||||
const std::string str = "=value";
|
|
||||||
|
|
||||||
std::string key;
|
|
||||||
std::string value;
|
|
||||||
|
|
||||||
bool ok = webcc::utility::SplitKV(str, '=', &key, &value);
|
|
||||||
EXPECT_TRUE(ok);
|
|
||||||
|
|
||||||
EXPECT_EQ("", key);
|
|
||||||
EXPECT_EQ("value", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(UtilityTest, SplitKV_NoValue) {
|
|
||||||
const std::string str = "key=";
|
|
||||||
|
|
||||||
std::string key;
|
|
||||||
std::string value;
|
|
||||||
|
|
||||||
bool ok = webcc::utility::SplitKV(str, '=', &key, &value);
|
|
||||||
EXPECT_TRUE(ok);
|
|
||||||
|
|
||||||
EXPECT_EQ("key", key);
|
|
||||||
EXPECT_EQ("", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(UtilityTest, SplitKV_NoKeyNoValue) {
|
|
||||||
const std::string str = "=";
|
|
||||||
|
|
||||||
std::string key;
|
|
||||||
std::string value;
|
|
||||||
|
|
||||||
bool ok = webcc::utility::SplitKV(str, '=', &key, &value);
|
|
||||||
EXPECT_TRUE(ok);
|
|
||||||
|
|
||||||
EXPECT_EQ("", key);
|
|
||||||
EXPECT_EQ("", value);
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
#include "webcc/body.h"
|
#include "webcc/body.h"
|
||||||
|
|
||||||
#include "boost/algorithm/string.hpp"
|
|
||||||
|
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
#include "webcc/utility.h"
|
#include "webcc/utility.h"
|
||||||
|
|
||||||
|
|||||||
+9
-10
@@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
|
|
||||||
#include "boost/algorithm/string.hpp"
|
|
||||||
|
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
|
#include "webcc/string.h"
|
||||||
#include "webcc/utility.h"
|
#include "webcc/utility.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
@@ -63,7 +62,7 @@ const std::string& Headers::Get(const std::string& key, bool* existed) const {
|
|||||||
std::vector<Header>::iterator Headers::Find(const std::string& key) {
|
std::vector<Header>::iterator Headers::Find(const std::string& key) {
|
||||||
auto it = headers_.begin();
|
auto it = headers_.begin();
|
||||||
for (; it != headers_.end(); ++it) {
|
for (; it != headers_.end(); ++it) {
|
||||||
if (boost::iequals(it->first, key)) {
|
if (iequals(it->first, key)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +74,7 @@ std::vector<Header>::iterator Headers::Find(const std::string& key) {
|
|||||||
static bool ParseValue(const std::string& str, const std::string& expected_key,
|
static bool ParseValue(const std::string& str, const std::string& expected_key,
|
||||||
std::string* value) {
|
std::string* value) {
|
||||||
std::string key;
|
std::string key;
|
||||||
if (!utility::SplitKV(str, '=', &key, value)) {
|
if (!split_kv(key, *value, str, '=')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,8 +123,8 @@ void ContentType::Init(const std::string& str) {
|
|||||||
other = str.substr(pos + 1);
|
other = str.substr(pos + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::trim(media_type_);
|
trim(media_type_);
|
||||||
boost::trim(other);
|
trim(other);
|
||||||
|
|
||||||
if (media_type_ == "multipart/form-data") {
|
if (media_type_ == "multipart/form-data") {
|
||||||
multipart_ = true;
|
multipart_ = true;
|
||||||
@@ -143,13 +142,13 @@ void ContentType::Init(const std::string& str) {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
static void Unquote(std::string& str) {
|
static inline void Unquote(std::string& str) {
|
||||||
boost::trim_if(str, boost::is_any_of("\""));
|
trim(str, "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContentDisposition::Init(const std::string& str) {
|
bool ContentDisposition::Init(const std::string& str) {
|
||||||
std::vector<std::string> parts;
|
std::vector<std::string> parts;
|
||||||
boost::split(parts, str, boost::is_any_of(";"));
|
split(parts, str, ';');
|
||||||
|
|
||||||
if (parts.empty()) {
|
if (parts.empty()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -162,7 +161,7 @@ bool ContentDisposition::Init(const std::string& str) {
|
|||||||
std::string key;
|
std::string key;
|
||||||
std::string value;
|
std::string value;
|
||||||
for (std::size_t i = 1; i < parts.size(); ++i) {
|
for (std::size_t i = 1; i < parts.size(); ++i) {
|
||||||
if (!utility::SplitKV(parts[i], '=', &key, &value)) {
|
if (!split_kv(key, value, parts[i], '=')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-23
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "boost/algorithm/string.hpp"
|
#include "webcc/string.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
@@ -21,29 +21,29 @@ const char DOUBLE_DASHES[2] = { '-', '-' };
|
|||||||
namespace media_types {
|
namespace media_types {
|
||||||
|
|
||||||
std::string FromExtension(const std::string& ext) {
|
std::string FromExtension(const std::string& ext) {
|
||||||
using boost::iequals;
|
std::string lext = tolower(ext);
|
||||||
|
|
||||||
if (iequals(ext, ".htm")) { return "text/html"; }
|
if (lext == ".htm") { return "text/html"; }
|
||||||
if (iequals(ext, ".html")) { return "text/html"; }
|
if (lext == ".html") { return "text/html"; }
|
||||||
if (iequals(ext, ".php")) { return "text/html"; }
|
if (lext == ".php") { return "text/html"; }
|
||||||
if (iequals(ext, ".css")) { return "text/css"; }
|
if (lext == ".css") { return "text/css"; }
|
||||||
if (iequals(ext, ".txt")) { return "text/plain"; }
|
if (lext == ".txt") { return "text/plain"; }
|
||||||
if (iequals(ext, ".js")) { return "application/javascript"; }
|
if (lext == ".js") { return "application/javascript"; }
|
||||||
if (iequals(ext, ".json")) { return "application/json"; }
|
if (lext == ".json") { return "application/json"; }
|
||||||
if (iequals(ext, ".xml")) { return "application/xml"; }
|
if (lext == ".xml") { return "application/xml"; }
|
||||||
if (iequals(ext, ".swf")) { return "application/x-shockwave-flash"; }
|
if (lext == ".swf") { return "application/x-shockwave-flash"; }
|
||||||
if (iequals(ext, ".flv")) { return "video/x-flv"; }
|
if (lext == ".flv") { return "video/x-flv"; }
|
||||||
if (iequals(ext, ".png")) { return "image/png"; }
|
if (lext == ".png") { return "image/png"; }
|
||||||
if (iequals(ext, ".jpe")) { return "image/jpeg"; }
|
if (lext == ".jpe") { return "image/jpeg"; }
|
||||||
if (iequals(ext, ".jpeg")) { return "image/jpeg"; }
|
if (lext == ".jpeg") { return "image/jpeg"; }
|
||||||
if (iequals(ext, ".jpg")) { return "image/jpeg"; }
|
if (lext == ".jpg") { return "image/jpeg"; }
|
||||||
if (iequals(ext, ".gif")) { return "image/gif"; }
|
if (lext == ".gif") { return "image/gif"; }
|
||||||
if (iequals(ext, ".bmp")) { return "image/bmp"; }
|
if (lext == ".bmp") { return "image/bmp"; }
|
||||||
if (iequals(ext, ".ico")) { return "image/vnd.microsoft.icon"; }
|
if (lext == ".ico") { return "image/vnd.microsoft.icon"; }
|
||||||
if (iequals(ext, ".tiff")) { return "image/tiff"; }
|
if (lext == ".tiff") { return "image/tiff"; }
|
||||||
if (iequals(ext, ".tif")) { return "image/tiff"; }
|
if (lext == ".tif") { return "image/tiff"; }
|
||||||
if (iequals(ext, ".svg")) { return "image/svg+xml"; }
|
if (lext == ".svg") { return "image/svg+xml"; }
|
||||||
if (iequals(ext, ".svgz")) { return "image/svg+xml"; }
|
if (lext == ".svgz") { return "image/svg+xml"; }
|
||||||
|
|
||||||
return "application/text";
|
return "application/text";
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-32
@@ -11,37 +11,6 @@
|
|||||||
|
|
||||||
#include "webcc/config.h"
|
#include "webcc/config.h"
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// Macros
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
|
||||||
#if _MSC_VER <= 1800 // VS 2013
|
|
||||||
|
|
||||||
// Does the compiler support "= default" for move copy constructor and
|
|
||||||
// move assignment operator?
|
|
||||||
#define WEBCC_DEFAULT_MOVE_COPY_ASSIGN 0
|
|
||||||
|
|
||||||
#define WEBCC_NOEXCEPT
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define WEBCC_DEFAULT_MOVE_COPY_ASSIGN 1
|
|
||||||
|
|
||||||
#define WEBCC_NOEXCEPT noexcept
|
|
||||||
|
|
||||||
#endif // _MSC_VER <= 1800
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// GCC, Clang, etc.
|
|
||||||
|
|
||||||
#define WEBCC_DEFAULT_MOVE_COPY_ASSIGN 1
|
|
||||||
|
|
||||||
#define WEBCC_NOEXCEPT noexcept
|
|
||||||
|
|
||||||
#endif // _MSC_VER
|
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -197,7 +166,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note that `noexcept` is required by GCC.
|
// Note that `noexcept` is required by GCC.
|
||||||
const char* what() const WEBCC_NOEXCEPT override{
|
const char* what() const noexcept override{
|
||||||
return message_.c_str();
|
return message_.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "boost/algorithm/string.hpp"
|
|
||||||
|
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
|
#include "webcc/string.h"
|
||||||
#include "webcc/utility.h"
|
#include "webcc/utility.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
@@ -53,7 +52,7 @@ bool Message::IsConnectionKeepAlive() const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boost::iequals(connection, "Keep-Alive")) {
|
if (iequals(connection, "Keep-Alive")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-9
@@ -1,7 +1,5 @@
|
|||||||
#include "webcc/parser.h"
|
#include "webcc/parser.h"
|
||||||
|
|
||||||
#include "boost/algorithm/string.hpp"
|
|
||||||
|
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
#include "webcc/message.h"
|
#include "webcc/message.h"
|
||||||
#include "webcc/string.h"
|
#include "webcc/string.h"
|
||||||
@@ -71,7 +69,7 @@ bool FileBodyHandler::OpenFile() {
|
|||||||
|
|
||||||
// Generate a random string as file name.
|
// Generate a random string as file name.
|
||||||
// A replacement of boost::filesystem::unique_path().
|
// A replacement of boost::filesystem::unique_path().
|
||||||
temp_path_ /= string::RandomString(10);
|
temp_path_ /= random_string(10);
|
||||||
|
|
||||||
LOG_VERB("Generate a temp path for streaming: %s",
|
LOG_VERB("Generate a temp path for streaming: %s",
|
||||||
temp_path_.string().c_str());
|
temp_path_.string().c_str());
|
||||||
@@ -252,16 +250,16 @@ bool Parser::GetNextLine(std::size_t off, std::string* line, bool erase) {
|
|||||||
|
|
||||||
bool Parser::ParseHeaderLine(const std::string& line) {
|
bool Parser::ParseHeaderLine(const std::string& line) {
|
||||||
Header header;
|
Header header;
|
||||||
if (!utility::SplitKV(line, ':', &header.first, &header.second)) {
|
if (!split_kv(header.first, header.second, line, ':')) {
|
||||||
LOG_ERRO("Invalid header: %s", line.c_str());
|
LOG_ERRO("Invalid header: %s", line.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boost::iequals(header.first, headers::kContentLength)) {
|
if (iequals(header.first, headers::kContentLength)) {
|
||||||
content_length_parsed_ = true;
|
content_length_parsed_ = true;
|
||||||
|
|
||||||
std::size_t content_length = kInvalidLength;
|
std::size_t content_length = kInvalidLength;
|
||||||
if (!utility::ToSize(header.second, 10, &content_length)) {
|
if (!to_size_t(header.second, 10, &content_length)) {
|
||||||
LOG_ERRO("Invalid content length: %s.", header.second.c_str());
|
LOG_ERRO("Invalid content length: %s.", header.second.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -269,13 +267,13 @@ bool Parser::ParseHeaderLine(const std::string& line) {
|
|||||||
LOG_INFO("Content length: %u.", content_length);
|
LOG_INFO("Content length: %u.", content_length);
|
||||||
content_length_ = content_length;
|
content_length_ = content_length;
|
||||||
|
|
||||||
} else if (boost::iequals(header.first, headers::kContentType)) {
|
} else if (iequals(header.first, headers::kContentType)) {
|
||||||
content_type_.Parse(header.second);
|
content_type_.Parse(header.second);
|
||||||
if (!content_type_.Valid()) {
|
if (!content_type_.Valid()) {
|
||||||
LOG_ERRO("Invalid content-type header: %s", header.second.c_str());
|
LOG_ERRO("Invalid content-type header: %s", header.second.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (boost::iequals(header.first, headers::kTransferEncoding)) {
|
} else if (iequals(header.first, headers::kTransferEncoding)) {
|
||||||
if (header.second == "chunked") {
|
if (header.second == "chunked") {
|
||||||
// The content is chunked.
|
// The content is chunked.
|
||||||
chunked_ = true;
|
chunked_ = true;
|
||||||
@@ -394,7 +392,7 @@ bool Parser::ParseChunkSize() {
|
|||||||
hex_str = line;
|
hex_str = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!utility::ToSize(hex_str, 16, &chunk_size_)) {
|
if (!to_size_t(hex_str, 16, &chunk_size_)) {
|
||||||
LOG_ERRO("Invalid chunk-size: %s.", hex_str.c_str());
|
LOG_ERRO("Invalid chunk-size: %s.", hex_str.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "webcc/base64.h"
|
#include "webcc/base64.h"
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
|
#include "webcc/string.h"
|
||||||
#include "webcc/utility.h"
|
#include "webcc/utility.h"
|
||||||
|
|
||||||
#if WEBCC_ENABLE_GZIP
|
#if WEBCC_ENABLE_GZIP
|
||||||
@@ -37,7 +38,7 @@ RequestPtr RequestBuilder::operator()() {
|
|||||||
} else if (!form_parts_.empty()) {
|
} else if (!form_parts_.empty()) {
|
||||||
// Another choice to generate the boundary is like what Apache does.
|
// Another choice to generate the boundary is like what Apache does.
|
||||||
// See: https://stackoverflow.com/a/5686863
|
// See: https://stackoverflow.com/a/5686863
|
||||||
auto boundary = utility::RandomUuid();
|
auto boundary = random_string(30);
|
||||||
|
|
||||||
request->SetContentType("multipart/form-data; boundary=" + boundary);
|
request->SetContentType("multipart/form-data; boundary=" + boundary);
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "boost/algorithm/string.hpp"
|
|
||||||
|
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
#include "webcc/request.h"
|
#include "webcc/request.h"
|
||||||
|
#include "webcc/string.h"
|
||||||
#include "webcc/utility.h"
|
#include "webcc/utility.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
@@ -36,7 +35,7 @@ bool RequestParser::OnHeadersEnd() {
|
|||||||
|
|
||||||
bool RequestParser::ParseStartLine(const std::string& line) {
|
bool RequestParser::ParseStartLine(const std::string& line) {
|
||||||
std::vector<std::string> strs;
|
std::vector<std::string> strs;
|
||||||
boost::split(strs, line, boost::is_any_of(" "), boost::token_compress_on);
|
split(strs, line, ' ', true);
|
||||||
|
|
||||||
if (strs.size() != 3) {
|
if (strs.size() != 3) {
|
||||||
return false;
|
return false;
|
||||||
@@ -190,7 +189,7 @@ bool RequestParser::ParsePartHeaders(bool* need_more_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Header header;
|
Header header;
|
||||||
if (!utility::SplitKV(line, ':', &header.first, &header.second)) {
|
if (!split_kv(header.first, header.second, line, ':')) {
|
||||||
LOG_ERRO("Invalid part header line: %s", line.c_str());
|
LOG_ERRO("Invalid part header line: %s", line.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -199,7 +198,7 @@ bool RequestParser::ParsePartHeaders(bool* need_more_data) {
|
|||||||
header.second.c_str());
|
header.second.c_str());
|
||||||
|
|
||||||
// Parse Content-Disposition.
|
// Parse Content-Disposition.
|
||||||
if (boost::iequals(header.first, headers::kContentDisposition)) {
|
if (iequals(header.first, headers::kContentDisposition)) {
|
||||||
ContentDisposition content_disposition(header.second);
|
ContentDisposition content_disposition(header.second);
|
||||||
if (!content_disposition.valid()) {
|
if (!content_disposition.valid()) {
|
||||||
LOG_ERRO("Invalid content-disposition header: %s",
|
LOG_ERRO("Invalid content-disposition header: %s",
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#include "webcc/response_parser.h"
|
#include "webcc/response_parser.h"
|
||||||
|
|
||||||
#include "boost/algorithm/string.hpp"
|
|
||||||
|
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
#include "webcc/response.h"
|
#include "webcc/response.h"
|
||||||
|
#include "webcc/string.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
@@ -54,7 +53,7 @@ bool ResponseParser::ParseStartLine(const std::string& line) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!boost::starts_with(parts[0], "HTTP/1.")) {
|
if (!starts_with(parts[0], "HTTP/1.")) {
|
||||||
LOG_ERRO("Invalid HTTP version: %s", parts[0].c_str());
|
LOG_ERRO("Invalid HTTP version: %s", parts[0].c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "boost/algorithm/string.hpp"
|
|
||||||
|
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
|
#include "webcc/string.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
@@ -60,7 +59,7 @@ ViewPtr Router::FindView(const std::string& method, const std::string& url,
|
|||||||
return route.view;
|
return route.view;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (boost::iequals(route.url, url)) {
|
if (iequals(route.url, url)) {
|
||||||
return route.view;
|
return route.view;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,7 +87,7 @@ bool Router::MatchView(const std::string& method, const std::string& url,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (boost::iequals(route.url, url)) {
|
if (iequals(route.url, url)) {
|
||||||
*stream = route.view->Stream(method);
|
*stream = route.view->Stream(method);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-9
@@ -3,10 +3,9 @@
|
|||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
namespace string {
|
|
||||||
|
|
||||||
// See: https://stackoverflow.com/a/24586587
|
// Ref: https://stackoverflow.com/a/24586587
|
||||||
std::string RandomString(std::size_t length) {
|
std::string random_string(std::size_t length) {
|
||||||
static const char chrs[] =
|
static const char chrs[] =
|
||||||
"0123456789"
|
"0123456789"
|
||||||
"abcdefghijklmnopqrstuvwxyz"
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
@@ -26,15 +25,31 @@ std::string RandomString(std::size_t length) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EqualsNoCase(const std::string& str1, const std::string& str2) {
|
bool to_size_t(const std::string& str, int base, std::size_t* size) {
|
||||||
if (str1.size() != str2.size()) {
|
try {
|
||||||
|
*size = static_cast<std::size_t>(std::stoul(str, 0, base));
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool split_kv(std::string& key, std::string& value, const std::string& str,
|
||||||
|
char delim, bool trim_spaces) {
|
||||||
|
std::size_t pos = str.find(delim);
|
||||||
|
if (pos == std::string::npos) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::equal(str1.begin(), str1.end(), str2.begin(), [](int c1, int c2) {
|
key = str.substr(0, pos);
|
||||||
return std::toupper(c1) == std::toupper(c2);
|
value = str.substr(pos + 1);
|
||||||
});
|
|
||||||
|
if (trim_spaces) {
|
||||||
|
trim(key);
|
||||||
|
trim(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace string
|
|
||||||
} // namespace webcc
|
} // namespace webcc
|
||||||
|
|||||||
+75
-10
@@ -7,22 +7,87 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
namespace string {
|
|
||||||
|
|
||||||
// Get a randomly generated string with the given length.
|
// Get a randomly generated string with the given length.
|
||||||
std::string RandomString(std::size_t length);
|
std::string random_string(std::size_t length);
|
||||||
|
|
||||||
// TODO: What about std::wstring?
|
// Convert string to size_t.
|
||||||
bool EqualsNoCase(const std::string& str1, const std::string& str2);
|
bool to_size_t(const std::string& str, int base, std::size_t* size);
|
||||||
|
|
||||||
template <class Container>
|
inline std::string toupper(std::string s) {
|
||||||
void Split(const std::string& str, Container& cont) {
|
std::transform(s.begin(), s.end(), s.begin(),
|
||||||
std::istringstream iss(str);
|
[](unsigned char c) { return std::toupper(c); });
|
||||||
std::copy(std::istream_iterator<std::string>(iss),
|
return s;
|
||||||
std::istream_iterator<std::string>(), std::back_inserter(cont));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace string
|
inline std::string tolower(std::string s) {
|
||||||
|
std::transform(s.begin(), s.end(), s.begin(),
|
||||||
|
[](unsigned char c) { return std::tolower(c); });
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool iequals(const std::string& str1, const std::string& str2) {
|
||||||
|
if (str1.size() != str2.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::equal(str1.begin(), str1.end(), str2.begin(), [](int c1, int c2) {
|
||||||
|
return std::toupper(c1) == std::toupper(c2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool starts_with(const std::string& str, const std::string& sub) {
|
||||||
|
if (sub.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return str.find(sub) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string& ltrim(std::string& str, const std::string& chars = "\t ") {
|
||||||
|
str.erase(0, str.find_first_not_of(chars));
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string& rtrim(std::string& str, const std::string& chars = "\t ") {
|
||||||
|
str.erase(str.find_last_not_of(chars) + 1);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string& trim(std::string& str, const std::string& chars = "\t ") {
|
||||||
|
return ltrim(rtrim(str, chars), chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
// \param compress_token Same as boost::token_compress_on, especially useful
|
||||||
|
// when the delimeter is space.
|
||||||
|
template <class Container>
|
||||||
|
void split(Container& cont, const std::string& str, char delim = ' ',
|
||||||
|
bool compress_token = false) {
|
||||||
|
std::size_t i = 0;
|
||||||
|
std::size_t p = 0;
|
||||||
|
|
||||||
|
i = str.find(delim);
|
||||||
|
|
||||||
|
while (i != std::string::npos) {
|
||||||
|
cont.push_back(str.substr(p, i - p));
|
||||||
|
p = i + 1;
|
||||||
|
|
||||||
|
if (compress_token) {
|
||||||
|
while (str[p] == delim) {
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i = str.find(delim, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
cont.push_back(str.substr(p, i - p));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split a key-value string.
|
||||||
|
// E.g., split "Connection: Keep-Alive".
|
||||||
|
bool split_kv(std::string& key, std::string& value, const std::string& str,
|
||||||
|
char delim, bool trim_spaces = true);
|
||||||
|
|
||||||
} // namespace webcc
|
} // namespace webcc
|
||||||
|
|
||||||
#endif // WEBCC_STRING_H_
|
#endif // WEBCC_STRING_H_
|
||||||
|
|||||||
+4
-4
@@ -4,8 +4,7 @@
|
|||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include "boost/algorithm/string/trim.hpp"
|
#include "webcc/string.h"
|
||||||
|
|
||||||
#include "webcc/utility.h"
|
#include "webcc/utility.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
@@ -238,7 +237,8 @@ void Url::AppendQuery(const std::string& key, const std::string& value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Url::Parse(const std::string& str) {
|
void Url::Parse(const std::string& str) {
|
||||||
std::string tmp = boost::trim_left_copy(str);
|
std::string tmp = str;
|
||||||
|
ltrim(tmp);
|
||||||
|
|
||||||
std::size_t p = std::string::npos;
|
std::size_t p = std::string::npos;
|
||||||
|
|
||||||
@@ -309,7 +309,7 @@ UrlQuery::UrlQuery(const std::string& encoded_str) {
|
|||||||
|
|
||||||
std::string key;
|
std::string key;
|
||||||
std::string value;
|
std::string value;
|
||||||
if (utility::SplitKV(kv, '=', &key, &value, false)) {
|
if (split_kv(key, value, kv, '=', false)) {
|
||||||
parameters_.push_back({ DecodeUnsafe(key), DecodeUnsafe(value) });
|
parameters_.push_back({ DecodeUnsafe(key), DecodeUnsafe(value) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-25
@@ -27,34 +27,9 @@ public:
|
|||||||
|
|
||||||
explicit Url(const std::string& str, bool encode = false);
|
explicit Url(const std::string& str, bool encode = false);
|
||||||
|
|
||||||
#if WEBCC_DEFAULT_MOVE_COPY_ASSIGN
|
|
||||||
|
|
||||||
Url(Url&&) = default;
|
Url(Url&&) = default;
|
||||||
Url& operator=(Url&&) = default;
|
Url& operator=(Url&&) = default;
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
Url(Url&& rhs)
|
|
||||||
: scheme_(std::move(rhs.scheme_)),
|
|
||||||
host_(std::move(rhs.host_)),
|
|
||||||
port_(std::move(rhs.port_)),
|
|
||||||
path_(std::move(rhs.path_)),
|
|
||||||
query_(std::move(rhs.query_)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Url& operator=(Url&& rhs) {
|
|
||||||
if (&rhs != this) {
|
|
||||||
scheme_ = std::move(rhs.scheme_);
|
|
||||||
host_ = std::move(rhs.host_);
|
|
||||||
port_ = std::move(rhs.port_);
|
|
||||||
path_ = std::move(rhs.path_);
|
|
||||||
query_ = std::move(rhs.query_);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // WEBCC_DEFAULT_MOVE_COPY_ASSIGN
|
|
||||||
|
|
||||||
const std::string& scheme() const {
|
const std::string& scheme() const {
|
||||||
return scheme_;
|
return scheme_;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-39
@@ -7,22 +7,12 @@
|
|||||||
#include <iomanip> // for put_time
|
#include <iomanip> // for put_time
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "boost/algorithm/string.hpp"
|
#include "webcc/string.h"
|
||||||
#include "boost/uuid/random_generator.hpp"
|
|
||||||
#include "boost/uuid/uuid_io.hpp"
|
|
||||||
|
|
||||||
#include "webcc/version.h"
|
#include "webcc/version.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
namespace utility {
|
namespace utility {
|
||||||
|
|
||||||
std::string RandomUuid() {
|
|
||||||
boost::uuids::uuid u = boost::uuids::random_generator()();
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << u;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& UserAgent() {
|
const std::string& UserAgent() {
|
||||||
static auto s_user_agent = std::string("Webcc/") + WEBCC_VERSION;
|
static auto s_user_agent = std::string("Webcc/") + WEBCC_VERSION;
|
||||||
return s_user_agent;
|
return s_user_agent;
|
||||||
@@ -35,33 +25,6 @@ std::string GetTimestamp() {
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SplitKV(const std::string& str, char delimiter, std::string* key,
|
|
||||||
std::string* value, bool trim) {
|
|
||||||
std::size_t pos = str.find(delimiter);
|
|
||||||
if (pos == std::string::npos) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*key = str.substr(0, pos);
|
|
||||||
*value = str.substr(pos + 1);
|
|
||||||
|
|
||||||
if (trim) {
|
|
||||||
boost::trim(*key);
|
|
||||||
boost::trim(*value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ToSize(const std::string& str, int base, std::size_t* size) {
|
|
||||||
try {
|
|
||||||
*size = static_cast<std::size_t>(std::stoul(str, 0, base));
|
|
||||||
} catch (const std::exception&) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t TellSize(const std::filesystem::path& path) {
|
std::size_t TellSize(const std::filesystem::path& path) {
|
||||||
// Flag "ate": seek to the end of stream immediately after open.
|
// Flag "ate": seek to the end of stream immediately after open.
|
||||||
std::ifstream stream{ path, std::ios::binary | std::ios::ate };
|
std::ifstream stream{ path, std::ios::binary | std::ios::ate };
|
||||||
@@ -91,7 +54,7 @@ bool ReadFile(const std::filesystem::path& path, std::string* output) {
|
|||||||
void DumpByLine(const std::string& data, std::ostream& os,
|
void DumpByLine(const std::string& data, std::ostream& os,
|
||||||
const std::string& prefix) {
|
const std::string& prefix) {
|
||||||
std::vector<std::string> lines;
|
std::vector<std::string> lines;
|
||||||
boost::split(lines, data, boost::is_any_of("\n"));
|
split(lines, data, '\n');
|
||||||
|
|
||||||
std::size_t size = 0;
|
std::size_t size = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,6 @@ class path;
|
|||||||
namespace webcc {
|
namespace webcc {
|
||||||
namespace utility {
|
namespace utility {
|
||||||
|
|
||||||
// Get a randomly generated UUID.
|
|
||||||
std::string RandomUuid();
|
|
||||||
|
|
||||||
// Get default user agent for HTTP headers.
|
// Get default user agent for HTTP headers.
|
||||||
const std::string& UserAgent();
|
const std::string& UserAgent();
|
||||||
|
|
||||||
@@ -26,14 +23,6 @@ const std::string& UserAgent();
|
|||||||
// See: https://tools.ietf.org/html/rfc7231#section-7.1.1.2
|
// See: https://tools.ietf.org/html/rfc7231#section-7.1.1.2
|
||||||
std::string GetTimestamp();
|
std::string GetTimestamp();
|
||||||
|
|
||||||
// Split a key-value string.
|
|
||||||
// E.g., split "Connection: Keep-Alive".
|
|
||||||
bool SplitKV(const std::string& str, char delimiter, std::string* key,
|
|
||||||
std::string* value, bool trim = true);
|
|
||||||
|
|
||||||
// Convert string to size_t.
|
|
||||||
bool ToSize(const std::string& str, int base, std::size_t* size);
|
|
||||||
|
|
||||||
// Tell the size in bytes of the given file.
|
// Tell the size in bytes of the given file.
|
||||||
// Return kInvalidLength (-1) on failure.
|
// Return kInvalidLength (-1) on failure.
|
||||||
std::size_t TellSize(const std::filesystem::path& path);
|
std::size_t TellSize(const std::filesystem::path& path);
|
||||||
|
|||||||
Reference in New Issue
Block a user