mirror of
https://github.com/yhirose/cpp-httplib
synced 2024-11-21 14:29:10 -07:00
* Fix #1973 * Fixed problems with 'Language for non-Unicode programs' setting on Windows * Fix problems on English locale
This commit is contained in:
parent
924f214303
commit
9dd565b6e3
3 changed files with 54 additions and 8 deletions
31
httplib.h
31
httplib.h
|
@ -2258,13 +2258,33 @@ make_basic_authentication_header(const std::string &username,
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
std::wstring u8string_to_wstring(const char *s) {
|
||||||
|
std::wstring ws;
|
||||||
|
auto len = static_cast<int>(strlen(s));
|
||||||
|
auto wlen = ::MultiByteToWideChar(CP_UTF8, 0, s, len, nullptr, 0);
|
||||||
|
if (wlen > 0) {
|
||||||
|
ws.resize(wlen);
|
||||||
|
wlen = ::MultiByteToWideChar(CP_UTF8, 0, s, len, const_cast<LPWSTR>(reinterpret_cast<LPCWSTR>(ws.data())), wlen);
|
||||||
|
if (wlen != ws.size()) {
|
||||||
|
ws.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ws;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct FileStat {
|
struct FileStat {
|
||||||
FileStat(const std::string &path);
|
FileStat(const std::string &path);
|
||||||
bool is_file() const;
|
bool is_file() const;
|
||||||
bool is_dir() const;
|
bool is_dir() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#if defined(_WIN32)
|
||||||
|
struct _stat st_;
|
||||||
|
#else
|
||||||
struct stat st_;
|
struct stat st_;
|
||||||
|
#endif
|
||||||
int ret_ = -1;
|
int ret_ = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2639,7 +2659,12 @@ inline bool is_valid_path(const std::string &path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline FileStat::FileStat(const std::string &path) {
|
inline FileStat::FileStat(const std::string &path) {
|
||||||
|
#if defined(_WIN32)
|
||||||
|
auto wpath = u8string_to_wstring(path.c_str());
|
||||||
|
ret_ = _wstat(wpath.c_str(), &st_);
|
||||||
|
#else
|
||||||
ret_ = stat(path.c_str(), &st_);
|
ret_ = stat(path.c_str(), &st_);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
inline bool FileStat::is_file() const {
|
inline bool FileStat::is_file() const {
|
||||||
return ret_ >= 0 && S_ISREG(st_.st_mode);
|
return ret_ >= 0 && S_ISREG(st_.st_mode);
|
||||||
|
@ -2909,10 +2934,8 @@ inline bool mmap::open(const char *path) {
|
||||||
close();
|
close();
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
std::wstring wpath;
|
auto wpath = u8string_to_wstring(path);
|
||||||
for (size_t i = 0; i < strlen(path); i++) {
|
if (wpath.empty()) { return false; }
|
||||||
wpath += path[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
|
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
|
||||||
hFile_ = ::CreateFile2(wpath.c_str(), GENERIC_READ, FILE_SHARE_READ,
|
hFile_ = ::CreateFile2(wpath.c_str(), GENERIC_READ, FILE_SHARE_READ,
|
||||||
|
|
30
test/test.cc
30
test/test.cc
|
@ -1,3 +1,4 @@
|
||||||
|
// NOTE: This file should be saved as UTF-8 w/ BOM
|
||||||
#include <httplib.h>
|
#include <httplib.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
@ -241,7 +242,7 @@ TEST(DecodeURLTest, PercentCharacter) {
|
||||||
detail::decode_url(
|
detail::decode_url(
|
||||||
R"(descrip=Gastos%20%C3%A1%C3%A9%C3%AD%C3%B3%C3%BA%C3%B1%C3%91%206)",
|
R"(descrip=Gastos%20%C3%A1%C3%A9%C3%AD%C3%B3%C3%BA%C3%B1%C3%91%206)",
|
||||||
false),
|
false),
|
||||||
R"(descrip=Gastos áéíóúñÑ 6)");
|
u8"descrip=Gastos áéíóúñÑ 6");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DecodeURLTest, PercentCharacterNUL) {
|
TEST(DecodeURLTest, PercentCharacterNUL) {
|
||||||
|
@ -267,9 +268,9 @@ TEST(EncodeQueryParamTest, ParseReservedCharactersTest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EncodeQueryParamTest, TestUTF8Characters) {
|
TEST(EncodeQueryParamTest, TestUTF8Characters) {
|
||||||
string chineseCharacters = "中国語";
|
string chineseCharacters = u8"中国語";
|
||||||
string russianCharacters = "дом";
|
string russianCharacters = u8"дом";
|
||||||
string brazilianCharacters = "óculos";
|
string brazilianCharacters = u8"óculos";
|
||||||
|
|
||||||
EXPECT_EQ(detail::encode_query_param(chineseCharacters),
|
EXPECT_EQ(detail::encode_query_param(chineseCharacters),
|
||||||
"%E4%B8%AD%E5%9B%BD%E8%AA%9E");
|
"%E4%B8%AD%E5%9B%BD%E8%AA%9E");
|
||||||
|
@ -5271,6 +5272,27 @@ TEST(MountTest, Redicect) {
|
||||||
EXPECT_EQ(StatusCode::OK_200, res->status);
|
EXPECT_EQ(StatusCode::OK_200, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(MountTest, MultibytesPathName) {
|
||||||
|
Server svr;
|
||||||
|
|
||||||
|
auto listen_thread = std::thread([&svr]() { svr.listen("localhost", PORT); });
|
||||||
|
auto se = detail::scope_exit([&] {
|
||||||
|
svr.stop();
|
||||||
|
listen_thread.join();
|
||||||
|
ASSERT_FALSE(svr.is_running());
|
||||||
|
});
|
||||||
|
|
||||||
|
svr.set_mount_point("/", "./www");
|
||||||
|
svr.wait_until_ready();
|
||||||
|
|
||||||
|
Client cli("localhost", PORT);
|
||||||
|
|
||||||
|
auto res = cli.Get(u8"/日本語Dir/日本語File.txt");
|
||||||
|
ASSERT_TRUE(res);
|
||||||
|
EXPECT_EQ(StatusCode::OK_200, res->status);
|
||||||
|
EXPECT_EQ(u8"日本語コンテンツ", res->body);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(KeepAliveTest, ReadTimeout) {
|
TEST(KeepAliveTest, ReadTimeout) {
|
||||||
Server svr;
|
Server svr;
|
||||||
|
|
||||||
|
|
1
test/www/日本語Dir/日本語File.txt
Normal file
1
test/www/日本語Dir/日本語File.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
日本語コンテンツ
|
Loading…
Reference in a new issue