Skip to content

Commit 9d12b3f

Browse files
committed
Fixed warnings and refactoring
1 parent 852a374 commit 9d12b3f

File tree

2 files changed

+78
-96
lines changed

2 files changed

+78
-96
lines changed

httplib.h

Lines changed: 55 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,14 @@ inline std::string from_i_to_hex(size_t n) {
12481248
return ret;
12491249
}
12501250

1251+
inline bool start_with(const std::string &a, const std::string &b) {
1252+
if (a.size() < b.size()) { return false; }
1253+
for (size_t i = 0; i < b.size(); i++) {
1254+
if (std::tolower(a[i]) != std::tolower(b[i])) { return false; }
1255+
}
1256+
return true;
1257+
}
1258+
12511259
inline size_t to_utf8(int code, char *buff) {
12521260
if (code < 0x0080) {
12531261
buff[0] = (code & 0x7F);
@@ -1441,44 +1449,40 @@ inline std::string file_extension(const std::string &path) {
14411449
return std::string();
14421450
}
14431451

1444-
inline std::pair<int, int> trim(const char *b, const char *e, int left,
1445-
int right) {
1446-
while (b + left < e && b[left] == ' ') {
1452+
inline bool is_space_or_tab(char c) { return c == ' ' || c == '\t'; }
1453+
1454+
inline std::pair<size_t, size_t> trim(const char *b, const char *e, size_t left,
1455+
size_t right) {
1456+
while (b + left < e && is_space_or_tab(b[left])) {
14471457
left++;
14481458
}
1449-
while (right - 1 >= 0 && b[right - 1] == ' ') {
1459+
while (right > 0 && is_space_or_tab(b[right - 1])) {
14501460
right--;
14511461
}
14521462
return std::make_pair(left, right);
14531463
}
14541464

1455-
inline void trim(std::string &s) {
1456-
auto is_not_space = [](int ch) { return !std::isspace(ch); };
1457-
s.erase(s.begin(), std::find_if(s.begin(), s.end(), is_not_space));
1458-
s.erase(std::find_if(s.rbegin(), s.rend(), is_not_space).base(), s.end());
1465+
inline std::string trim_copy(const std::string &s) {
1466+
auto r = trim(s.data(), s.data() + s.size(), 0, s.size());
1467+
return s.substr(r.first, r.second - r.first);
14591468
}
14601469

1461-
14621470
template <class Fn> void split(const char *b, const char *e, char d, Fn fn) {
1463-
int i = 0;
1464-
int beg = 0;
1471+
size_t i = 0;
1472+
size_t beg = 0;
14651473

14661474
while (e ? (b + i < e) : (b[i] != '\0')) {
14671475
if (b[i] == d) {
14681476
auto r = trim(b, e, beg, i);
1469-
if (r.first < r.second) {
1470-
fn(&b[r.first], &b[r.second]);
1471-
}
1477+
if (r.first < r.second) { fn(&b[r.first], &b[r.second]); }
14721478
beg = i + 1;
14731479
}
14741480
i++;
14751481
}
14761482

14771483
if (i) {
14781484
auto r = trim(b, e, beg, i);
1479-
if (r.first < r.second) {
1480-
fn(&b[r.first], &b[r.second]);
1481-
}
1485+
if (r.first < r.second) { fn(&b[r.first], &b[r.second]); }
14821486
}
14831487
}
14841488

@@ -2429,26 +2433,34 @@ inline uint64_t get_header_value<uint64_t>(const Headers &headers,
24292433
return def;
24302434
}
24312435

2432-
inline void parse_header(const char *beg, const char *end, Headers &headers) {
2436+
template <typename T>
2437+
inline bool parse_header(const char *beg, const char *end, T fn) {
2438+
// Skip trailing spaces and tabs.
2439+
while (beg < end && is_space_or_tab(end[-1])) {
2440+
end--;
2441+
}
2442+
24332443
auto p = beg;
24342444
while (p < end && *p != ':') {
24352445
p++;
24362446
}
2447+
2448+
if (p == end) { return false; }
2449+
2450+
auto key_end = p;
2451+
2452+
if (*p++ != ':') { return false; }
2453+
2454+
while (p < end && is_space_or_tab(*p)) {
2455+
p++;
2456+
}
2457+
24372458
if (p < end) {
2438-
auto key_end = p;
2439-
p++; // skip ':'
2440-
while (p < end && (*p == ' ' || *p == '\t')) {
2441-
p++;
2442-
}
2443-
if (p < end) {
2444-
auto val_begin = p;
2445-
while (p < end) {
2446-
p++;
2447-
}
2448-
headers.emplace(std::string(beg, key_end),
2449-
decode_url(std::string(val_begin, end), true));
2450-
}
2459+
fn(std::string(beg, key_end), decode_url(std::string(p, end), true));
2460+
return true;
24512461
}
2462+
2463+
return false;
24522464
}
24532465

24542466
inline bool read_headers(Stream &strm, Headers &headers) {
@@ -2467,13 +2479,13 @@ inline bool read_headers(Stream &strm, Headers &headers) {
24672479
continue; // Skip invalid line.
24682480
}
24692481

2470-
// Skip trailing spaces and tabs.
2482+
// Exclude CRLF
24712483
auto end = line_reader.ptr() + line_reader.size() - 2;
2472-
while (line_reader.ptr() < end && (end[-1] == ' ' || end[-1] == '\t')) {
2473-
end--;
2474-
}
24752484

2476-
parse_header(line_reader.ptr(), end, headers);
2485+
parse_header(line_reader.ptr(), end,
2486+
[&](std::string &&key, std::string &&val) {
2487+
headers.emplace(std::move(key), std::move(val));
2488+
});
24772489
}
24782490

24792491
return true;
@@ -2835,18 +2847,6 @@ inline bool redirect(T &cli, const Request &req, Response &res,
28352847
return ret;
28362848
}
28372849

2838-
inline bool contains_header(const std::string &header, const std::string &name) {
2839-
if (header.length() >= name.length()) {
2840-
for (int i = 0; i < name.length(); ++i) {
2841-
if (std::tolower(header[i]) != std::tolower(name[i])) {
2842-
return false;
2843-
}
2844-
}
2845-
return true;
2846-
}
2847-
return false;
2848-
}
2849-
28502850
inline std::string params_to_query_str(const Params &params) {
28512851
std::string query;
28522852

@@ -2871,7 +2871,7 @@ inline void parse_query_text(const std::string &s, Params &params) {
28712871
}
28722872
});
28732873

2874-
if(!key.empty()) {
2874+
if (!key.empty()) {
28752875
params.emplace(decode_url(key, true), decode_url(val, true));
28762876
}
28772877
});
@@ -2975,15 +2975,13 @@ class MultipartFormDataParser {
29752975
break;
29762976
}
29772977

2978-
auto header = buf_.substr(0, pos);
2979-
{
2978+
static const std::string header_name = "content-type:";
2979+
const auto header = buf_.substr(0, pos);
2980+
if (start_with(header, header_name)) {
2981+
file_.content_type = trim_copy(header.substr(header_name.size()));
2982+
} else {
29802983
std::smatch m;
2981-
const std::string header_name = "content-type:";
2982-
if (contains_header(header, header_name)) {
2983-
header.erase(header.begin(), header.begin() + header_name.size());
2984-
trim(header);
2985-
file_.content_type = header;
2986-
} else if (std::regex_match(header, m, re_content_disposition)) {
2984+
if (std::regex_match(header, m, re_content_disposition)) {
29872985
file_.name = m[1];
29882986
file_.filename = m[2];
29892987
}

test/test.cc

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,11 @@ TEST(StartupTest, WSAStartup) {
4343
ASSERT_EQ(0, ret);
4444
}
4545
#endif
46+
4647
TEST(TrimTests, TrimStringTests) {
47-
{
48-
std::string s = "abc";
49-
detail::trim(s);
50-
EXPECT_EQ("abc", s);
51-
}
52-
{
53-
std::string s = " abc ";
54-
detail::trim(s);
55-
EXPECT_EQ("abc", s);
56-
}
57-
{
58-
std::string s = "";
59-
detail::trim(s);
60-
EXPECT_TRUE( s.empty() );
61-
}
48+
EXPECT_EQ("abc", detail::trim_copy("abc"));
49+
EXPECT_EQ("abc", detail::trim_copy(" abc "));
50+
EXPECT_TRUE(detail::trim_copy("").empty());
6251
}
6352

6453
TEST(SplitTest, ParseQueryString) {
@@ -100,7 +89,6 @@ TEST(SplitTest, ParseInvalidQueryTests) {
10089
}
10190
}
10291

103-
10492
TEST(ParseQueryTest, ParseQueryString) {
10593
string s = "key1=val1&key2=val2&key3=val3";
10694
Params dic;
@@ -1827,8 +1815,7 @@ TEST_F(ServerTest, MultipartFormData) {
18271815
{"file1", "h\ne\n\nl\nl\no\n", "hello.txt", "text/plain"},
18281816
{"file2", "{\n \"world\", true\n}\n", "world.json", "application/json"},
18291817
{"file3", "", "", "application/octet-stream"},
1830-
{"file4", "", "", " application/json tmp-string "}
1831-
};
1818+
{"file4", "", "", " application/json tmp-string "}};
18321819

18331820
auto res = cli_.Post("/multipart", items);
18341821

@@ -2201,7 +2188,6 @@ TEST_F(ServerTest, GetStreamedChunkedWithGzip2) {
22012188
EXPECT_EQ(std::string("123456789"), res->body);
22022189
}
22032190

2204-
22052191
TEST(GzipDecompressor, ChunkedDecompression) {
22062192
std::string data;
22072193
for (size_t i = 0; i < 32 * 1024; ++i) {
@@ -2212,10 +2198,8 @@ TEST(GzipDecompressor, ChunkedDecompression) {
22122198
{
22132199
httplib::detail::gzip_compressor compressor;
22142200
bool result = compressor.compress(
2215-
data.data(),
2216-
data.size(),
2217-
/*last=*/true,
2218-
[&] (const char* data, size_t size) {
2201+
data.data(), data.size(),
2202+
/*last=*/true, [&](const char *data, size_t size) {
22192203
compressed_data.insert(compressed_data.size(), data, size);
22202204
return true;
22212205
});
@@ -2226,15 +2210,16 @@ TEST(GzipDecompressor, ChunkedDecompression) {
22262210
{
22272211
httplib::detail::gzip_decompressor decompressor;
22282212

2229-
// Chunk size is chosen specificaly to have a decompressed chunk size equal to 16384 bytes
2230-
// 16384 bytes is the size of decompressor output buffer
2213+
// Chunk size is chosen specificaly to have a decompressed chunk size equal
2214+
// to 16384 bytes 16384 bytes is the size of decompressor output buffer
22312215
size_t chunk_size = 130;
2232-
for (size_t chunk_begin = 0; chunk_begin < compressed_data.size(); chunk_begin += chunk_size) {
2233-
size_t current_chunk_size = std::min(compressed_data.size() - chunk_begin, chunk_size);
2216+
for (size_t chunk_begin = 0; chunk_begin < compressed_data.size();
2217+
chunk_begin += chunk_size) {
2218+
size_t current_chunk_size =
2219+
std::min(compressed_data.size() - chunk_begin, chunk_size);
22342220
bool result = decompressor.decompress(
2235-
compressed_data.data() + chunk_begin,
2236-
current_chunk_size,
2237-
[&] (const char* data, size_t size) {
2221+
compressed_data.data() + chunk_begin, current_chunk_size,
2222+
[&](const char *data, size_t size) {
22382223
decompressed_data.insert(decompressed_data.size(), data, size);
22392224
return true;
22402225
});
@@ -2819,15 +2804,14 @@ TEST(StreamingTest, NoContentLengthStreaming) {
28192804
Server svr;
28202805

28212806
svr.Get("/stream", [](const Request & /*req*/, Response &res) {
2822-
res.set_content_provider(
2823-
"text/plain", [](size_t offset, DataSink &sink) {
2824-
if (offset < 6) {
2825-
sink.os << (offset < 3 ? "a" : "b");
2826-
} else {
2827-
sink.done();
2828-
}
2829-
return true;
2830-
});
2807+
res.set_content_provider("text/plain", [](size_t offset, DataSink &sink) {
2808+
if (offset < 6) {
2809+
sink.os << (offset < 3 ? "a" : "b");
2810+
} else {
2811+
sink.done();
2812+
}
2813+
return true;
2814+
});
28312815
});
28322816

28332817
auto listen_thread = std::thread([&svr]() { svr.listen("localhost", PORT); });

0 commit comments

Comments
 (0)