Skip to content

Commit

Permalink
Resolve #1973 (#1976)
Browse files Browse the repository at this point in the history
* Fix #1973

* Fixed problems with 'Language for non-Unicode programs' setting on Windows

* Fix problems on English locale
  • Loading branch information
yhirose authored Nov 14, 2024
1 parent 924f214 commit 9dd565b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 8 deletions.
31 changes: 27 additions & 4 deletions httplib.h
Original file line number Diff line number Diff line change
Expand Up @@ -2258,13 +2258,33 @@ make_basic_authentication_header(const std::string &username,

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 {
FileStat(const std::string &path);
bool is_file() const;
bool is_dir() const;

private:
#if defined(_WIN32)
struct _stat st_;
#else
struct stat st_;
#endif
int ret_ = -1;
};

Expand Down Expand Up @@ -2639,7 +2659,12 @@ inline bool is_valid_path(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_);
#endif
}
inline bool FileStat::is_file() const {
return ret_ >= 0 && S_ISREG(st_.st_mode);
Expand Down Expand Up @@ -2909,10 +2934,8 @@ inline bool mmap::open(const char *path) {
close();

#if defined(_WIN32)
std::wstring wpath;
for (size_t i = 0; i < strlen(path); i++) {
wpath += path[i];
}
auto wpath = u8string_to_wstring(path);
if (wpath.empty()) { return false; }

#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
hFile_ = ::CreateFile2(wpath.c_str(), GENERIC_READ, FILE_SHARE_READ,
Expand Down
30 changes: 26 additions & 4 deletions test/test.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// NOTE: This file should be saved as UTF-8 w/ BOM
#include <httplib.h>
#include <signal.h>

Expand Down Expand Up @@ -241,7 +242,7 @@ TEST(DecodeURLTest, PercentCharacter) {
detail::decode_url(
R"(descrip=Gastos%20%C3%A1%C3%A9%C3%AD%C3%B3%C3%BA%C3%B1%C3%91%206)",
false),
R"(descrip=Gastos áéíóúñÑ 6)");
u8"descrip=Gastos áéíóúñÑ 6");
}

TEST(DecodeURLTest, PercentCharacterNUL) {
Expand All @@ -267,9 +268,9 @@ TEST(EncodeQueryParamTest, ParseReservedCharactersTest) {
}

TEST(EncodeQueryParamTest, TestUTF8Characters) {
string chineseCharacters = "中国語";
string russianCharacters = "дом";
string brazilianCharacters = "óculos";
string chineseCharacters = u8"中国語";
string russianCharacters = u8"дом";
string brazilianCharacters = u8"óculos";

EXPECT_EQ(detail::encode_query_param(chineseCharacters),
"%E4%B8%AD%E5%9B%BD%E8%AA%9E");
Expand Down Expand Up @@ -5271,6 +5272,27 @@ TEST(MountTest, Redicect) {
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) {
Server svr;

Expand Down
1 change: 1 addition & 0 deletions test/www/日本語Dir/日本語File.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
日本語コンテンツ

0 comments on commit 9dd565b

Please sign in to comment.