Browse Source

fix defaultLargeFileHandler not support chinese path (#720)

add hv::utf8_to_ansi and hv::ansi_to_utf8 function to hstring.h
宅の士 8 months ago
parent
commit
ba162bd501
4 changed files with 41 additions and 16 deletions
  1. 9 8
      cpputil/hstring.cpp
  2. 24 3
      cpputil/hstring.h
  3. 7 4
      http/server/HttpHandler.cpp
  4. 1 1
      http/server/HttpHandler.h

+ 9 - 8
cpputil/hstring.cpp

@@ -226,24 +226,25 @@ std::string NetAddr::to_string(const char* ip, int port) {
 }
 
 #ifdef OS_WIN
-std::string wchar_to_utf8(const std::wstring &wstr) {
+std::string wchar_to_string(const UINT codePage, const std::wstring &wstr) {
   std::string str(4 * wstr.size() + 1, '\0');
   str.resize(WideCharToMultiByte(
-    CP_UTF8, 0, 
-    wstr.c_str(), wstr.size(), 
-    const_cast<char*>(str.data()), str.size(), 
+    codePage, 0,
+    wstr.c_str(), wstr.size(),
+    const_cast<char*>(str.data()), str.size(),
     NULL, NULL));
   return str;
 }
 
-std::wstring utf8_to_wchar(const std::string &str) {
-  std::wstring wstr(2 * str.size() + 1, '\0');
+std::wstring string_to_wchar(const UINT codePage, const std::string &str) {
+  std::wstring wstr(2 * str.size() + 2, '\0');
   wstr.resize(MultiByteToWideChar(
-    CP_UTF8, 0, 
-    str.c_str(), str.size(), 
+    codePage, 0,
+    str.c_str(), str.size(),
     const_cast<wchar_t*>(wstr.data()), wstr.size()));
   return wstr;
 }
+
 #endif // OS_WIN
 
 } // end namespace hv

+ 24 - 3
cpputil/hstring.h

@@ -88,10 +88,31 @@ struct HV_EXPORT NetAddr {
     static std::string to_string(const char* ip, int port);
 };
 
-// windows wchar and utf8 conver
+// windows wchar and utf8/ansi conver
 #ifdef OS_WIN
-HV_EXPORT std::string wchar_to_utf8(const std::wstring &wstr);
-HV_EXPORT std::wstring utf8_to_wchar(const std::string &str);
+HV_EXPORT std::string wchar_to_string(const UINT codePage, const std::wstring &wstr);
+HV_EXPORT std::wstring string_to_wchar(const UINT codePage, const std::string &str);
+
+HV_INLINE std::string wchar_to_utf8(const std::wstring &wstr) {
+    return wchar_to_string(CP_UTF8, wstr);
+}
+
+HV_INLINE std::string wchar_to_ansi(const std::wstring &wstr) {
+    return wchar_to_string(CP_ACP, wstr);
+}
+
+HV_INLINE std::wstring utf8_to_wchar(const std::string &str) {
+    return string_to_wchar(CP_UTF8, str);
+}
+
+HV_INLINE std::string utf8_to_ansi(const std::string &str) {
+    return wchar_to_string(CP_ACP, string_to_wchar(CP_UTF8, str));
+}
+
+HV_INLINE std::string ansi_to_utf8(const std::string &str) {
+    return wchar_to_string(CP_UTF8, string_to_wchar(CP_ACP, str));
+}
+
 #endif // OS_WIN
 
 } // end namespace hv

+ 7 - 4
http/server/HttpHandler.cpp

@@ -585,7 +585,7 @@ int HttpHandler::defaultStaticHandler() {
             if (service->largeFileHandler) {
                 status_code = customHttpHandler(service->largeFileHandler);
             } else {
-                status_code = defaultLargeFileHandler();
+                status_code = defaultLargeFileHandler(filepath);
             }
         }
         return status_code;
@@ -604,7 +604,7 @@ int HttpHandler::defaultStaticHandler() {
             if (service->largeFileHandler) {
                 status_code = customHttpHandler(service->largeFileHandler);
             } else {
-                status_code = defaultLargeFileHandler();
+                status_code = defaultLargeFileHandler(filepath);
             }
         } else {
             status_code = HTTP_STATUS_NOT_FOUND;
@@ -629,10 +629,9 @@ int HttpHandler::defaultStaticHandler() {
     return status_code;
 }
 
-int HttpHandler::defaultLargeFileHandler() {
+int HttpHandler::defaultLargeFileHandler(const std::string &filepath) {
     if (!writer) return HTTP_STATUS_NOT_IMPLEMENTED;
     if (!isFileOpened()) {
-        std::string filepath = service->GetStaticFilepath(req->Path().c_str());
         if (filepath.empty() || openFile(filepath.c_str()) != 0) {
             return HTTP_STATUS_NOT_FOUND;
         }
@@ -874,7 +873,11 @@ int HttpHandler::openFile(const char* filepath) {
     closeFile();
     file = new LargeFile;
     file->timer = INVALID_TIMER_ID;
+#ifdef OS_WIN
+    return file->open(hv::utf8_to_ansi(filepath).c_str(), "rb");
+#else
     return file->open(filepath, "rb");
+#endif
 }
 
 bool HttpHandler::isFileOpened() {

+ 1 - 1
http/server/HttpHandler.h

@@ -156,7 +156,7 @@ private:
     // default handlers
     int defaultRequestHandler();
     int defaultStaticHandler();
-    int defaultLargeFileHandler();
+    int defaultLargeFileHandler(const std::string &filepath);
     int defaultErrorHandler();
     int customHttpHandler(const http_handler& handler);
     int invokeHttpHandler(const http_handler* handler);