simplify string utilities
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
#include "boost/filesystem/fstream.hpp"
|
||||
#include "boost/filesystem/operations.hpp"
|
||||
|
||||
@@ -299,7 +300,7 @@ TEST(ClientTest, Post) {
|
||||
|
||||
static bfs::path GenerateTempFile(const std::string& data) {
|
||||
try {
|
||||
bfs::path path = bfs::temp_directory_path() / webcc::random_string(10);
|
||||
bfs::path path = bfs::temp_directory_path() / webcc::RandomString(10);
|
||||
|
||||
bfs::ofstream ofs;
|
||||
ofs.open(path, std::ios::binary);
|
||||
@@ -419,24 +420,24 @@ TEST(ClientTest, KeepAlive) {
|
||||
// Keep-Alive by default.
|
||||
auto r = session.Send(webcc::RequestBuilder{}.Get(url)());
|
||||
|
||||
EXPECT_TRUE(webcc::iequals(r->GetHeader("Connection"), "Keep-alive"));
|
||||
EXPECT_TRUE(boost::iequals(r->GetHeader("Connection"), "Keep-alive"));
|
||||
|
||||
// Close by setting Connection header directly.
|
||||
r = session.Send(webcc::RequestBuilder{}.Get(url).
|
||||
Header("Connection", "Close")
|
||||
());
|
||||
|
||||
EXPECT_TRUE(webcc::iequals(r->GetHeader("Connection"), "Close"));
|
||||
EXPECT_TRUE(boost::iequals(r->GetHeader("Connection"), "Close"));
|
||||
|
||||
// Close by using request builder.
|
||||
r = session.Send(webcc::RequestBuilder{}.Get(url).KeepAlive(false)());
|
||||
|
||||
EXPECT_TRUE(webcc::iequals(r->GetHeader("Connection"), "Close"));
|
||||
EXPECT_TRUE(boost::iequals(r->GetHeader("Connection"), "Close"));
|
||||
|
||||
// Keep-Alive explicitly by using request builder.
|
||||
r = session.Send(webcc::RequestBuilder{}.Get(url).KeepAlive(true)());
|
||||
|
||||
EXPECT_TRUE(webcc::iequals(r->GetHeader("Connection"), "Keep-alive"));
|
||||
EXPECT_TRUE(boost::iequals(r->GetHeader("Connection"), "Keep-alive"));
|
||||
|
||||
} catch (const webcc::Error& error) {
|
||||
std::cerr << error << std::endl;
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
#include "boost/filesystem/operations.hpp"
|
||||
|
||||
#include "json/json.h"
|
||||
|
||||
#include "webcc/string.h"
|
||||
|
||||
#include "book_json.h"
|
||||
|
||||
namespace bfs = boost::filesystem;
|
||||
@@ -180,7 +179,7 @@ bool BookClient::CheckPhoto(const bfs::path& photo) {
|
||||
}
|
||||
|
||||
auto ext = photo.extension().string();
|
||||
if (!webcc::iequals(ext, ".jpg") && !webcc::iequals(ext, ".jpeg")) {
|
||||
if (!boost::iequals(ext, ".jpg") && !boost::iequals(ext, ".jpeg")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+28
-46
@@ -2,31 +2,13 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
|
||||
#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");
|
||||
TEST(StringTest, Split) {
|
||||
std::vector<boost::string_view> parts;
|
||||
webcc::Split("GET /path/to HTTP/1.1", ' ', false, &parts);
|
||||
|
||||
EXPECT_EQ(3, parts.size());
|
||||
EXPECT_EQ("GET", parts[0]);
|
||||
@@ -34,15 +16,15 @@ TEST(StringTest, split) {
|
||||
EXPECT_EQ("HTTP/1.1", parts[2]);
|
||||
}
|
||||
|
||||
TEST(StringTest, split_token_compress_off) {
|
||||
TEST(StringTest, Split_TokenCompressOff) {
|
||||
std::string str = "one,two,,three,,";
|
||||
std::vector<std::string> parts;
|
||||
std::vector<boost::string_view> parts;
|
||||
|
||||
// Same as:
|
||||
// boost::split(parts, str, boost::is_any_of(","),
|
||||
// boost::token_compress_off);
|
||||
|
||||
webcc::split(parts, str, ',', false);
|
||||
webcc::Split(str, ',', false, &parts);
|
||||
|
||||
EXPECT_EQ(6, parts.size());
|
||||
EXPECT_EQ("one", parts[0]);
|
||||
@@ -53,14 +35,14 @@ TEST(StringTest, split_token_compress_off) {
|
||||
EXPECT_EQ("", parts[5]);
|
||||
}
|
||||
|
||||
TEST(StringTest, split_token_compress_on) {
|
||||
TEST(StringTest, Split_TokenCompressOn) {
|
||||
std::string str = "one,two,,three,,";
|
||||
std::vector<std::string> parts;
|
||||
std::vector<boost::string_view> parts;
|
||||
|
||||
// Same as:
|
||||
// boost::split(parts, str, boost::is_any_of(","),
|
||||
// boost::token_compress_on);
|
||||
webcc::split(parts, str, ',', true);
|
||||
webcc::Split(str, ',', true, &parts);
|
||||
|
||||
EXPECT_EQ(4, parts.size());
|
||||
EXPECT_EQ("one", parts[0]);
|
||||
@@ -69,9 +51,9 @@ TEST(StringTest, split_token_compress_on) {
|
||||
EXPECT_EQ("", parts[3]);
|
||||
}
|
||||
|
||||
TEST(StringTest, split_new_line) {
|
||||
std::vector<std::string> lines;
|
||||
webcc::split(lines, "line one\nline two\nline 3", '\n');
|
||||
TEST(StringTest, Split_NewLine) {
|
||||
std::vector<boost::string_view> lines;
|
||||
webcc::Split("line one\nline two\nline 3", '\n', false, &lines);
|
||||
|
||||
EXPECT_EQ(3, lines.size());
|
||||
EXPECT_EQ("line one", lines[0]);
|
||||
@@ -79,24 +61,24 @@ TEST(StringTest, split_new_line) {
|
||||
EXPECT_EQ("line 3", lines[2]);
|
||||
}
|
||||
|
||||
TEST(UtilityTest, split_kv) {
|
||||
TEST(StringTest, SplitKV) {
|
||||
const std::string str = "key=value";
|
||||
|
||||
std::string key;
|
||||
std::string value;
|
||||
bool ok = webcc::split_kv(key, value, str, '=');
|
||||
bool ok = webcc::SplitKV(str, '=', true, &key, &value);
|
||||
|
||||
EXPECT_EQ(true, ok);
|
||||
EXPECT_EQ("key", key);
|
||||
EXPECT_EQ("value", value);
|
||||
}
|
||||
|
||||
TEST(UtilityTest, split_kv_other_delim) {
|
||||
TEST(StringTest, SplitKV_OtherDelim) {
|
||||
const std::string str = "key:value";
|
||||
|
||||
std::string key;
|
||||
std::string value;
|
||||
bool ok = webcc::split_kv(key, value, str, ':');
|
||||
bool ok = webcc::SplitKV(str, ':', true, &key, &value);
|
||||
|
||||
EXPECT_TRUE(ok);
|
||||
|
||||
@@ -104,12 +86,12 @@ TEST(UtilityTest, split_kv_other_delim) {
|
||||
EXPECT_EQ("value", value);
|
||||
}
|
||||
|
||||
TEST(UtilityTest, split_kv_spaces) {
|
||||
TEST(StringTest, SplitKV_Spaces) {
|
||||
const std::string str = " key = value ";
|
||||
|
||||
std::string key;
|
||||
std::string value;
|
||||
bool ok = webcc::split_kv(key, value, str, '=');
|
||||
bool ok = webcc::SplitKV(str, '=', true, &key, &value);
|
||||
|
||||
EXPECT_TRUE(ok);
|
||||
|
||||
@@ -117,12 +99,12 @@ TEST(UtilityTest, split_kv_spaces) {
|
||||
EXPECT_EQ("value", value);
|
||||
}
|
||||
|
||||
TEST(UtilityTest, split_kv_spaces_no_trim) {
|
||||
TEST(StringTest, SplitKV_SpacesNoTrim) {
|
||||
const std::string str = " key = value ";
|
||||
|
||||
std::string key;
|
||||
std::string value;
|
||||
bool ok = webcc::split_kv(key, value, str, '=', false);
|
||||
bool ok = webcc::SplitKV(str, '=', false, &key, &value);
|
||||
|
||||
EXPECT_TRUE(ok);
|
||||
|
||||
@@ -130,12 +112,12 @@ TEST(UtilityTest, split_kv_spaces_no_trim) {
|
||||
EXPECT_EQ(" value ", value);
|
||||
}
|
||||
|
||||
TEST(UtilityTest, split_kv_no_key) {
|
||||
TEST(StringTest, SplitKV_NoKey) {
|
||||
const std::string str = "=value";
|
||||
|
||||
std::string key;
|
||||
std::string value;
|
||||
bool ok = webcc::split_kv(key, value, str, '=');
|
||||
bool ok = webcc::SplitKV(str, '=', true, &key, &value);
|
||||
|
||||
EXPECT_TRUE(ok);
|
||||
|
||||
@@ -143,12 +125,12 @@ TEST(UtilityTest, split_kv_no_key) {
|
||||
EXPECT_EQ("value", value);
|
||||
}
|
||||
|
||||
TEST(UtilityTest, split_kv_no_value) {
|
||||
TEST(StringTest, SplitKV_NoValue) {
|
||||
const std::string str = "key=";
|
||||
|
||||
std::string key;
|
||||
std::string value;
|
||||
bool ok = webcc::split_kv(key, value, str, '=');
|
||||
bool ok = webcc::SplitKV(str, '=', true, &key, &value);
|
||||
|
||||
EXPECT_TRUE(ok);
|
||||
|
||||
@@ -156,12 +138,12 @@ TEST(UtilityTest, split_kv_no_value) {
|
||||
EXPECT_EQ("", value);
|
||||
}
|
||||
|
||||
TEST(UtilityTest, split_kv_no_key_no_value) {
|
||||
TEST(StringTest, SplitKV_NoKeyNoValue) {
|
||||
const std::string str = "=";
|
||||
|
||||
std::string key;
|
||||
std::string value;
|
||||
bool ok = webcc::split_kv(key, value, str, '=');
|
||||
bool ok = webcc::SplitKV(str, '=', true, &key, &value);
|
||||
|
||||
EXPECT_TRUE(ok);
|
||||
|
||||
|
||||
+10
-8
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <codecvt>
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
|
||||
#include "webcc/logger.h"
|
||||
#include "webcc/string.h"
|
||||
#include "webcc/utility.h"
|
||||
@@ -64,7 +66,7 @@ const std::string& Headers::Get(const std::string& key, bool* existed) const {
|
||||
std::vector<Header>::iterator Headers::Find(const std::string& key) {
|
||||
auto it = headers_.begin();
|
||||
for (; it != headers_.end(); ++it) {
|
||||
if (iequals(it->first, key)) {
|
||||
if (boost::iequals(it->first, key)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -76,7 +78,7 @@ std::vector<Header>::iterator Headers::Find(const std::string& key) {
|
||||
static bool ParseValue(const std::string& str, const std::string& expected_key,
|
||||
std::string* value) {
|
||||
std::string key;
|
||||
if (!split_kv(key, *value, str, '=')) {
|
||||
if (!SplitKV(str, '=', true, &key, value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -125,8 +127,8 @@ void ContentType::Init(const std::string& str) {
|
||||
other = str.substr(pos + 1);
|
||||
}
|
||||
|
||||
trim(media_type_);
|
||||
trim(other);
|
||||
boost::trim(media_type_);
|
||||
boost::trim(other);
|
||||
|
||||
if (media_type_ == "multipart/form-data") {
|
||||
multipart_ = true;
|
||||
@@ -145,12 +147,12 @@ void ContentType::Init(const std::string& str) {
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static inline void Unquote(std::string& str) {
|
||||
trim(str, "\"");
|
||||
boost::trim_if(str, boost::is_any_of("\""));
|
||||
}
|
||||
|
||||
bool ContentDisposition::Init(const std::string& str) {
|
||||
std::vector<std::string> parts;
|
||||
split(parts, str, ';');
|
||||
std::vector<boost::string_view> parts;
|
||||
Split(str, ';', false, &parts);
|
||||
|
||||
if (parts.empty()) {
|
||||
return false;
|
||||
@@ -163,7 +165,7 @@ bool ContentDisposition::Init(const std::string& str) {
|
||||
std::string key;
|
||||
std::string value;
|
||||
for (std::size_t i = 1; i < parts.size(); ++i) {
|
||||
if (!split_kv(key, value, parts[i], '=')) {
|
||||
if (!SplitKV(parts[i].to_string(), '=', true, &key, &value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "webcc/string.h"
|
||||
#include "boost/algorithm/string/case_conv.hpp"
|
||||
|
||||
namespace webcc {
|
||||
|
||||
@@ -21,7 +21,7 @@ const char DOUBLE_DASHES[2] = { '-', '-' };
|
||||
namespace media_types {
|
||||
|
||||
std::string FromExtension(const std::string& ext) {
|
||||
std::string lext = tolower(ext);
|
||||
std::string lext = boost::to_lower_copy(ext);
|
||||
|
||||
if (lext == ".htm") { return "text/html"; }
|
||||
if (lext == ".html") { return "text/html"; }
|
||||
|
||||
+3
-2
@@ -2,8 +2,9 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
|
||||
#include "webcc/logger.h"
|
||||
#include "webcc/string.h"
|
||||
#include "webcc/utility.h"
|
||||
|
||||
namespace webcc {
|
||||
@@ -52,7 +53,7 @@ bool Message::IsConnectionKeepAlive() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (iequals(connection, "Keep-Alive")) {
|
||||
if (boost::iequals(connection, "Keep-Alive")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+10
-9
@@ -1,5 +1,6 @@
|
||||
#include "webcc/parser.h"
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
#include "boost/filesystem/operations.hpp"
|
||||
|
||||
#include "webcc/logger.h"
|
||||
@@ -73,7 +74,7 @@ bool FileBodyHandler::OpenFile() {
|
||||
|
||||
// Generate a random string as file name.
|
||||
// A replacement of boost::filesystem::unique_path().
|
||||
temp_path_ /= random_string(10);
|
||||
temp_path_ /= RandomString(10);
|
||||
|
||||
LOG_VERB("Generate a temp path for streaming: %s",
|
||||
temp_path_.string().c_str());
|
||||
@@ -259,30 +260,30 @@ bool Parser::GetNextLine(std::size_t off, std::string* line, bool erase) {
|
||||
|
||||
bool Parser::ParseHeaderLine(const std::string& line) {
|
||||
Header header;
|
||||
if (!split_kv(header.first, header.second, line, ':')) {
|
||||
if (!SplitKV(line, ':', true, &header.first, &header.second)) {
|
||||
LOG_ERRO("Invalid header: %s", line.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iequals(header.first, headers::kContentLength)) {
|
||||
if (boost::iequals(header.first, headers::kContentLength)) {
|
||||
content_length_parsed_ = true;
|
||||
|
||||
std::size_t content_length = kInvalidLength;
|
||||
if (!to_size_t(header.second, 10, &content_length)) {
|
||||
LOG_ERRO("Invalid content length: %s.", header.second.c_str());
|
||||
if (!ToSizeT(header.second, 10, &content_length)) {
|
||||
LOG_ERRO("Invalid content length: %s", header.second.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("Content length: %u.", content_length);
|
||||
LOG_INFO("Content length: %u", content_length);
|
||||
content_length_ = content_length;
|
||||
|
||||
} else if (iequals(header.first, headers::kContentType)) {
|
||||
} else if (boost::iequals(header.first, headers::kContentType)) {
|
||||
content_type_.Parse(header.second);
|
||||
if (!content_type_.Valid()) {
|
||||
LOG_ERRO("Invalid content-type header: %s", header.second.c_str());
|
||||
return false;
|
||||
}
|
||||
} else if (iequals(header.first, headers::kTransferEncoding)) {
|
||||
} else if (boost::iequals(header.first, headers::kTransferEncoding)) {
|
||||
if (header.second == "chunked") {
|
||||
// The content is chunked.
|
||||
chunked_ = true;
|
||||
@@ -401,7 +402,7 @@ bool Parser::ParseChunkSize() {
|
||||
hex_str = line;
|
||||
}
|
||||
|
||||
if (!to_size_t(hex_str, 16, &chunk_size_)) {
|
||||
if (!ToSizeT(hex_str, 16, &chunk_size_)) {
|
||||
LOG_ERRO("Invalid chunk-size: %s", hex_str.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ RequestPtr RequestBuilder::operator()() {
|
||||
} else if (!form_parts_.empty()) {
|
||||
// Another choice to generate the boundary is like what Apache does.
|
||||
// See: https://stackoverflow.com/a/5686863
|
||||
auto boundary = random_string(30);
|
||||
auto boundary = RandomString(30);
|
||||
|
||||
request->SetContentType("multipart/form-data; boundary=" + boundary);
|
||||
|
||||
|
||||
+14
-13
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
|
||||
#include "webcc/logger.h"
|
||||
#include "webcc/request.h"
|
||||
#include "webcc/string.h"
|
||||
@@ -34,15 +36,15 @@ bool RequestParser::OnHeadersEnd() {
|
||||
}
|
||||
|
||||
bool RequestParser::ParseStartLine(const std::string& line) {
|
||||
std::vector<std::string> strs;
|
||||
split(strs, line, ' ', true);
|
||||
std::vector<boost::string_view> parts;
|
||||
Split(line, ' ', true, &parts);
|
||||
|
||||
if (strs.size() != 3) {
|
||||
if (parts.size() != 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
request_->set_method(std::move(strs[0]));
|
||||
request_->set_url(Url(strs[1]));
|
||||
request_->set_method(std::move(parts[0].to_string()));
|
||||
request_->set_url(Url{ parts[1].to_string() });
|
||||
|
||||
// HTTP version is ignored.
|
||||
|
||||
@@ -95,7 +97,7 @@ bool RequestParser::ParseMultipartContent(const char* data,
|
||||
if (ParsePartHeaders(&need_more_data)) {
|
||||
// Go to next step.
|
||||
step_ = Step::kHeadersParsed;
|
||||
LOG_INFO("Part headers just ended.");
|
||||
LOG_INFO("Part headers just ended");
|
||||
continue;
|
||||
} else {
|
||||
if (need_more_data) {
|
||||
@@ -129,7 +131,7 @@ bool RequestParser::ParseMultipartContent(const char* data,
|
||||
// +2 for including the CRLF after the boundary.
|
||||
pending_data_.erase(0, off + count + 2);
|
||||
} else {
|
||||
LOG_ERRO("Invalid part data. off=%u", off);
|
||||
LOG_ERRO("Invalid part data, off=%u", off);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -152,7 +154,7 @@ bool RequestParser::ParseMultipartContent(const char* data,
|
||||
}
|
||||
|
||||
if (step_ == Step::kEnded) {
|
||||
LOG_INFO("Multipart data has ended.");
|
||||
LOG_INFO("Multipart data has ended");
|
||||
|
||||
// Create a body and set to the request.
|
||||
|
||||
@@ -186,16 +188,16 @@ bool RequestParser::ParsePartHeaders(bool* need_more_data) {
|
||||
}
|
||||
|
||||
Header header;
|
||||
if (!split_kv(header.first, header.second, line, ':')) {
|
||||
if (!SplitKV(line, ':', true, &header.first, &header.second)) {
|
||||
LOG_ERRO("Invalid part header line: %s", line.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("Part header (%s: %s).", header.first.c_str(),
|
||||
LOG_INFO("Part header (%s: %s)", header.first.c_str(),
|
||||
header.second.c_str());
|
||||
|
||||
// Parse Content-Disposition.
|
||||
if (iequals(header.first, headers::kContentDisposition)) {
|
||||
if (boost::iequals(header.first, headers::kContentDisposition)) {
|
||||
ContentDisposition content_disposition(header.second);
|
||||
if (!content_disposition.valid()) {
|
||||
LOG_ERRO("Invalid content-disposition header: %s",
|
||||
@@ -217,8 +219,7 @@ bool RequestParser::ParsePartHeaders(bool* need_more_data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RequestParser::GetNextBoundaryLine(std::size_t* b_off,
|
||||
std::size_t* b_len,
|
||||
bool RequestParser::GetNextBoundaryLine(std::size_t* b_off, std::size_t* b_len,
|
||||
bool* ended) {
|
||||
std::size_t off = 0;
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include "webcc/response_parser.h"
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
|
||||
#include "webcc/logger.h"
|
||||
#include "webcc/response.h"
|
||||
#include "webcc/string.h"
|
||||
|
||||
namespace webcc {
|
||||
|
||||
@@ -25,7 +26,8 @@ void SplitStartLine(const std::string& line, std::vector<std::string>* parts) {
|
||||
parts->push_back(line.substr(off, pos - off));
|
||||
off = pos + 1;
|
||||
|
||||
for (; off < line.size() && line[off] == SPACE; ++off) {}
|
||||
for (; off < line.size() && line[off] == SPACE; ++off) {
|
||||
}
|
||||
}
|
||||
|
||||
if (off < line.size()) {
|
||||
@@ -53,7 +55,7 @@ bool ResponseParser::ParseStartLine(const std::string& line) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!starts_with(parts[0], "HTTP/1.")) {
|
||||
if (!boost::starts_with(parts[0], "HTTP/1.")) {
|
||||
LOG_ERRO("Invalid HTTP version: %s", parts[0].c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
+4
-3
@@ -2,8 +2,9 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
|
||||
#include "webcc/logger.h"
|
||||
#include "webcc/string.h"
|
||||
|
||||
namespace webcc {
|
||||
|
||||
@@ -59,7 +60,7 @@ ViewPtr Router::FindView(const std::string& method, const std::string& url,
|
||||
return route.view;
|
||||
}
|
||||
} else {
|
||||
if (iequals(route.url, url)) {
|
||||
if (boost::iequals(route.url, url)) {
|
||||
return route.view;
|
||||
}
|
||||
}
|
||||
@@ -87,7 +88,7 @@ bool Router::MatchView(const std::string& method, const std::string& url,
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (iequals(route.url, url)) {
|
||||
if (boost::iequals(route.url, url)) {
|
||||
*stream = route.view->Stream(method);
|
||||
return true;
|
||||
}
|
||||
|
||||
+35
-10
@@ -2,10 +2,12 @@
|
||||
|
||||
#include <random>
|
||||
|
||||
#include "boost/algorithm/string/trim.hpp"
|
||||
|
||||
namespace webcc {
|
||||
|
||||
// Ref: https://stackoverflow.com/a/24586587
|
||||
std::string random_string(std::size_t length) {
|
||||
std::string RandomString(std::size_t length) {
|
||||
static const char chrs[] =
|
||||
"0123456789"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
@@ -13,7 +15,7 @@ std::string random_string(std::size_t length) {
|
||||
|
||||
thread_local static std::mt19937 rg{ std::random_device{}() };
|
||||
thread_local static std::uniform_int_distribution<std::string::size_type>
|
||||
pick(0, sizeof(chrs) - 2);
|
||||
pick{ 0, sizeof(chrs) - 2 };
|
||||
|
||||
std::string s;
|
||||
s.reserve(length);
|
||||
@@ -25,7 +27,7 @@ std::string random_string(std::size_t length) {
|
||||
return s;
|
||||
}
|
||||
|
||||
bool to_size_t(const std::string& str, int base, std::size_t* size) {
|
||||
bool ToSizeT(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&) {
|
||||
@@ -34,19 +36,42 @@ bool to_size_t(const std::string& str, int base, std::size_t* size) {
|
||||
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);
|
||||
void Split(boost::string_view input, char delim, bool compress_token,
|
||||
std::vector<boost::string_view>* output) {
|
||||
std::size_t i = 0;
|
||||
std::size_t p = 0;
|
||||
|
||||
i = input.find(delim);
|
||||
|
||||
while (i != boost::string_view::npos) {
|
||||
output->emplace_back(input.substr(p, i - p));
|
||||
p = i + 1;
|
||||
|
||||
if (compress_token) {
|
||||
while (input[p] == delim) {
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
i = input.find(delim, p);
|
||||
}
|
||||
|
||||
output->emplace_back(input.substr(p, i - p));
|
||||
}
|
||||
|
||||
bool SplitKV(const std::string& input, char delim, bool trim_spaces,
|
||||
std::string* key, std::string* value) {
|
||||
std::size_t pos = input.find(delim);
|
||||
if (pos == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
key = str.substr(0, pos);
|
||||
value = str.substr(pos + 1);
|
||||
*key = input.substr(0, pos);
|
||||
*value = input.substr(pos + 1);
|
||||
|
||||
if (trim_spaces) {
|
||||
trim(key);
|
||||
trim(value);
|
||||
boost::trim(*key);
|
||||
boost::trim(*value);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+13
-75
@@ -1,92 +1,30 @@
|
||||
#ifndef WEBCC_STRING_H_
|
||||
#define WEBCC_STRING_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "boost/utility/string_view.hpp"
|
||||
|
||||
namespace webcc {
|
||||
|
||||
// Get a randomly generated string with the given length.
|
||||
std::string random_string(std::size_t length);
|
||||
std::string RandomString(std::size_t length);
|
||||
|
||||
// Convert string to size_t.
|
||||
bool to_size_t(const std::string& str, int base, std::size_t* size);
|
||||
// Just a wrapper of std::stoul.
|
||||
bool ToSizeT(const std::string& str, int base, std::size_t* size);
|
||||
|
||||
inline std::string toupper(std::string s) {
|
||||
std::transform(s.begin(), s.end(), s.begin(),
|
||||
[](unsigned char c) { return std::toupper(c); });
|
||||
return s;
|
||||
}
|
||||
|
||||
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 string without copy.
|
||||
// |compress_token| is the same as boost::token_compress_on for boost::split.
|
||||
void Split(boost::string_view input, char delim, bool compress_token,
|
||||
std::vector<boost::string_view>* output);
|
||||
|
||||
// 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);
|
||||
// TODO: Use string_view (blocked by trim)
|
||||
bool SplitKV(const std::string& input, char delim, bool trim_spaces,
|
||||
std::string* key, std::string* value);
|
||||
|
||||
} // namespace webcc
|
||||
|
||||
|
||||
+9
-3
@@ -4,6 +4,8 @@
|
||||
#include <cctype>
|
||||
#include <functional>
|
||||
|
||||
#include "boost/algorithm/string/trim.hpp"
|
||||
|
||||
#include "webcc/string.h"
|
||||
#include "webcc/utility.h"
|
||||
|
||||
@@ -238,7 +240,7 @@ void Url::AppendQuery(const std::string& key, const std::string& value,
|
||||
|
||||
void Url::Parse(const std::string& str) {
|
||||
std::string tmp = str;
|
||||
ltrim(tmp);
|
||||
boost::trim_left(tmp);
|
||||
|
||||
std::size_t p = std::string::npos;
|
||||
|
||||
@@ -314,7 +316,7 @@ UrlQuery::UrlQuery(const std::string& encoded_str) {
|
||||
|
||||
std::string key;
|
||||
std::string value;
|
||||
if (split_kv(key, value, kv, '=', false)) {
|
||||
if (SplitKV(kv, '=', false, &key, &value)) {
|
||||
parameters_.push_back({ DecodeUnsafe(key), DecodeUnsafe(value) });
|
||||
}
|
||||
}
|
||||
@@ -349,7 +351,7 @@ void UrlQuery::Remove(const std::string& key) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string UrlQuery::ToString() const {
|
||||
std::string UrlQuery::ToString(bool encode) const {
|
||||
if (parameters_.empty()) {
|
||||
return "";
|
||||
}
|
||||
@@ -363,7 +365,11 @@ std::string UrlQuery::ToString() const {
|
||||
str += parameters_[i].first + "=" + parameters_[i].second;
|
||||
}
|
||||
|
||||
if (encode) {
|
||||
return Url::EncodeQuery(str);
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
UrlQuery::ConstIterator UrlQuery::Find(const std::string& key) const {
|
||||
|
||||
+2
-2
@@ -109,9 +109,9 @@ public:
|
||||
|
||||
void Remove(const std::string& key);
|
||||
|
||||
// Return encoded query string joined with '&'.
|
||||
// Return query string, encoded or not, joined with '&'.
|
||||
// E.g., "item=12731&color=blue&size=large".
|
||||
std::string ToString() const;
|
||||
std::string ToString(bool encode = true) const;
|
||||
|
||||
private:
|
||||
using ConstIterator = std::vector<Parameter>::const_iterator;
|
||||
|
||||
+4
-4
@@ -80,16 +80,16 @@ bool ReadFile(const bfs::path& path, std::string* output) {
|
||||
|
||||
void DumpByLine(const std::string& data, std::ostream& os,
|
||||
const std::string& prefix) {
|
||||
std::vector<std::string> lines;
|
||||
split(lines, data, '\n');
|
||||
std::vector<boost::string_view> lines;
|
||||
Split(data, '\n', false, &lines);
|
||||
|
||||
std::size_t size = 0;
|
||||
|
||||
for (const std::string& line : lines) {
|
||||
for (const auto& line : lines) {
|
||||
os << prefix;
|
||||
|
||||
if (line.size() + size > kMaxDumpSize) {
|
||||
os.write(line.c_str(), kMaxDumpSize - size);
|
||||
os.write(line.data(), kMaxDumpSize - size);
|
||||
os << "..." << std::endl;
|
||||
break;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user