Skip to content

Commit fa4dfd8

Browse files
committed
fix windows defaultStaticHandler performance bug
fix http chinese name file cache bug support http windows chinese name index_of view add windows high-performance wchar_to_utf8 and utf8_to_wchar
1 parent 73084bb commit fa4dfd8

File tree

4 files changed

+56
-28
lines changed

4 files changed

+56
-28
lines changed

Diff for: cpputil/hdir.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "hplatform.h"
44

55
#ifdef OS_WIN
6+
#include "hstring.h" // import hv::utf8_to_wchar hv::wchar_to_utf8
67
//FILETIME starts from 1601-01-01 UTC, epoch from 1970-01-01 UTC
78
//FILETIME unit (100ns)
89
#define FILETIME_EPOCH_DIFF 11644473600 // s
@@ -61,15 +62,15 @@ int listdir(const char* dir, std::list<hdir_t>& dirs) {
6162
#elif defined(OS_WIN)
6263
// FindFirstFile -> FindNextFile -> FindClose
6364
strcat(path, "*");
64-
WIN32_FIND_DATAA data;
65-
HANDLE h = FindFirstFileA(path, &data);
65+
WIN32_FIND_DATAW data;
66+
HANDLE h = FindFirstFileW(hv::utf8_to_wchar(path).c_str(), &data);
6667
if (h == NULL) {
6768
return -1;
6869
}
6970
hdir_t tmp;
7071
do {
7172
memset(&tmp, 0, sizeof(hdir_t));
72-
strncpy(tmp.name, data.cFileName, sizeof(tmp.name));
73+
strncpy(tmp.name, hv::wchar_to_utf8(data.cFileName).c_str(), sizeof(tmp.name));
7374
tmp.type = 'f';
7475
if (data.dwFileAttributes & _A_SUBDIR) {
7576
tmp.type = 'd';
@@ -80,7 +81,7 @@ int listdir(const char* dir, std::list<hdir_t>& dirs) {
8081
tmp.mtime = FileTime2Epoch(data.ftLastWriteTime);
8182
tmp.ctime = FileTime2Epoch(data.ftCreationTime);
8283
dirs.push_back(tmp);
83-
} while (FindNextFileA(h, &data));
84+
} while (FindNextFileW(h, &data));
8485
FindClose(h);
8586
#endif
8687
dirs.sort(less);

Diff for: cpputil/hstring.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -225,4 +225,25 @@ std::string NetAddr::to_string(const char* ip, int port) {
225225
return hv::asprintf(fmt, ip, port);
226226
}
227227

228+
#ifdef OS_WIN
229+
std::string wchar_to_utf8(const std::wstring &wstr) {
230+
std::string str(4 * wstr.size() + 1, '\0');
231+
str.resize(WideCharToMultiByte(
232+
CP_UTF8, 0,
233+
wstr.c_str(), wstr.size(),
234+
const_cast<char*>(str.data()), str.size(),
235+
NULL, NULL));
236+
return str;
237+
}
238+
239+
std::wstring utf8_to_wchar(const std::string &str) {
240+
std::wstring wstr(2 * str.size() + 1, '\0');
241+
wstr.resize(MultiByteToWideChar(
242+
CP_UTF8, 0,
243+
str.c_str(), str.size(),
244+
const_cast<wchar_t*>(wstr.data()), wstr.size()));
245+
return wstr;
246+
}
247+
#endif // OS_WIN
248+
228249
} // end namespace hv

Diff for: cpputil/hstring.h

+6
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ struct HV_EXPORT NetAddr {
8888
static std::string to_string(const char* ip, int port);
8989
};
9090

91+
// windows wchar and utf8 conver
92+
#ifdef OS_WIN
93+
HV_EXPORT std::string wchar_to_utf8(const std::wstring &wstr);
94+
HV_EXPORT std::wstring utf8_to_wchar(const std::string &str);
95+
#endif // OS_WIN
96+
9197
} // end namespace hv
9298

9399
#endif // HV_STRING_H_

Diff for: http/server/FileCache.cpp

+24-24
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
#include "httpdef.h" // import http_content_type_str_by_suffix
99
#include "http_page.h" // import make_index_of_page
1010

11-
#ifdef _MSC_VER
12-
#include <codecvt>
11+
#ifdef OS_WIN
12+
#include "hstring.h" // import hv::utf8_to_wchar
1313
#endif
1414

1515
#define ETAG_FMT "\"%zx-%zx\""
@@ -19,27 +19,26 @@ FileCache::FileCache() {
1919
expired_time = 60; // s
2020
}
2121

22-
static int hv_open(char const* filepath, int flags) {
23-
#ifdef _MSC_VER
24-
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv;
25-
auto wfilepath = conv.from_bytes(filepath);
26-
int fd = _wopen(wfilepath.c_str(), flags);
27-
#else
28-
int fd = open(filepath, flags);
29-
#endif
30-
return fd;
31-
}
32-
3322
file_cache_ptr FileCache::Open(const char* filepath, OpenParam* param) {
3423
std::lock_guard<std::mutex> locker(mutex_);
3524
file_cache_ptr fc = Get(filepath);
25+
#ifdef OS_WIN
26+
std::wstring wfilepath;
27+
#endif
3628
bool modified = false;
3729
if (fc) {
3830
time_t now = time(NULL);
3931
if (now - fc->stat_time > stat_interval) {
40-
modified = fc->is_modified();
4132
fc->stat_time = now;
4233
fc->stat_cnt++;
34+
#ifdef OS_WIN
35+
wfilepath = hv::utf8_to_wchar(filepath);
36+
now = fc->st.st_mtime;
37+
_wstat(wfilepath.c_str(), (struct _stat*)&fc->st);
38+
modified = now != fc->st.st_mtime;
39+
#else
40+
modified = fc->is_modified();
41+
#endif
4342
}
4443
if (param->need_read) {
4544
if (!modified && fc->is_complete()) {
@@ -48,31 +47,32 @@ file_cache_ptr FileCache::Open(const char* filepath, OpenParam* param) {
4847
}
4948
}
5049
if (fc == NULL || modified || param->need_read) {
50+
struct stat st;
5151
int flags = O_RDONLY;
5252
#ifdef O_BINARY
5353
flags |= O_BINARY;
5454
#endif
55-
int fd = hv_open(filepath, flags);
56-
if (fd < 0) {
5755
#ifdef OS_WIN
56+
if(wfilepath.empty()) wfilepath = hv::utf8_to_wchar(filepath);
57+
const int fd = _wopen(wfilepath.c_str(), flags);
58+
if (fd < 0) {
5859
// NOTE: open(dir) return -1 on windows
59-
if (!hv_isdir(filepath)) {
60+
_wstat(wfilepath.c_str(), (struct _stat*)&st);
61+
if(!S_ISDIR(st.st_mode)) {
6062
param->error = ERR_OPEN_FILE;
6163
return NULL;
6264
}
65+
}
6366
#else
67+
const int fd = open(filepath, flags);
68+
if (fd < 0) {
6469
param->error = ERR_OPEN_FILE;
6570
return NULL;
66-
#endif
6771
}
72+
#endif
6873
defer(if (fd > 0) { close(fd); })
6974
if (fc == NULL) {
70-
struct stat st;
71-
if (fd > 0) {
72-
fstat(fd, &st);
73-
} else {
74-
stat(filepath, &st);
75-
}
75+
if (fd > 0) fstat(fd, &st);
7676
if (S_ISREG(st.st_mode) ||
7777
(S_ISDIR(st.st_mode) &&
7878
filepath[strlen(filepath)-1] == '/')) {

0 commit comments

Comments
 (0)