Skip to content

Commit

Permalink
fix: query string parsing issue
Browse files Browse the repository at this point in the history
`AtlUnescapeString` cannot parse '+' as space in query string, use WinRT Uri class instead.
  • Loading branch information
seven-mile committed Sep 2, 2023
1 parent 8d6afbb commit 53260ee
Show file tree
Hide file tree
Showing 5 changed files with 8 additions and 58 deletions.
Binary file modified DanmakuServer.rc
Binary file not shown.
2 changes: 1 addition & 1 deletion app.manifest
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.5.2.2" name="UFCase.app"/>
<assemblyIdentity version="1.5.3.0" name="SevenMile.DanmakuServer"/>

<dependency>
<dependentAssembly>
Expand Down
2 changes: 1 addition & 1 deletion main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class ShellIconWnd
td.dwFlags = TDF_ENABLE_HYPERLINKS;
td.pszMainIcon = MAKEINTRESOURCE(m_CurrentIconResource);
td.pszWindowTitle = L"About";
td.pszMainInstruction = L"Danmaku Server 1.1";
td.pszMainInstruction = L"Danmaku Server 1.5.3";
td.pszContent =
LR"(Please check our <a href="https://github.com/seven-mile/DanmakuServer">GitHub Repo</a> for more information.
The danmaku server is hosted on :7654 port, access <a href="http://localhost:7654/danmaku?name=danmaku%20server&content=hello,%20world%F0%9F%92%98">this url</a> for sample danmaku effect.)";
Expand Down
1 change: 0 additions & 1 deletion resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// 供 DanmakuServer.rc 使用
//
#define IDI_DANMAKU 101
#define IDI_ICON1 103
#define IDI_SETTINGS 103
#define IDM_TRAY 40003
#define IDMI_EXIT 40004
Expand Down
61 changes: 6 additions & 55 deletions server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,55 +57,6 @@ void SendHttpJsonResponse(HANDLE req_queue, HTTP_REQUEST &req, USHORT status,
));
}

std::wstring UrlDecodeWString(std::wstring const &inputw) {
std::string result;
DWORD cnt;

std::string inputa;
inputa.resize(inputw.size() + 1);
winrt::check_bool(AtlUnicodeToUTF8(inputw.c_str(), inputw.size(), inputa.data(), inputw.size() + 1));

AtlUnescapeUrl(inputa.c_str(), result.data(), &cnt, DWORD(result.size()));
result.resize(cnt);
winrt::check_bool(AtlUnescapeUrl(inputa.c_str(), result.data(), &cnt, DWORD(result.size())));
result.resize(strlen(result.data()));

return LPWSTR(ATL::CA2W(result.c_str(), CP_UTF8));
}

std::map<std::wstring, std::wstring> ParseQueryString(std::wstring_view query_string) {
std::map<std::wstring, std::wstring> result;

if (query_string.data() == nullptr)
return result;

// eat '?'
query_string = query_string.substr(1);

// Split the query_string by '&' to get individual key-value pairs
std::wstring key_value_pair;
std::wstringstream ss{std::wstring{query_string}};
while (std::getline(ss, key_value_pair, L'&')) {
// Split each key-value pair by '='
std::wstring key, value;
size_t equal_pos = key_value_pair.find(L'=');
if (equal_pos != std::wstring::npos) {
key = key_value_pair.substr(0, equal_pos);
value = key_value_pair.substr(equal_pos + 1);
} else {
key = key_value_pair;
value = L"";
}

key = UrlDecodeWString(key);
value = UrlDecodeWString(value);

result[key] = value;
}

return result;
}

DanmakuServer::DanmakuServer(danmaku_handler_t handler) {

cancel_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
Expand Down Expand Up @@ -166,16 +117,16 @@ DanmakuServer::DanmakuServer(danmaku_handler_t handler) {

bool handled = false;
if (req.Verb == HttpVerbGET) {
std::wstring_view abs_path{req.CookedUrl.pAbsPath, req.CookedUrl.AbsPathLength / sizeof(wchar_t)};
std::wstring_view query_string{req.CookedUrl.pQueryString, req.CookedUrl.QueryStringLength / sizeof(wchar_t)};
winrt::Windows::Foundation::Uri url{req.CookedUrl.pFullUrl};

if (abs_path.starts_with(L"/version")) {
if (url.Path().starts_with(L"/version")) {
handled = true;
SendHttpJsonResponse(req_queue, req, 200, "OK", R"({"version": 1, "repo": "https://github.com/seven-mile/DanmakuServer"})");
} else if (abs_path.starts_with(L"/danmaku")) {
} else if (url.Path().starts_with(L"/danmaku")) {
handled = true;
auto args = ParseQueryString(query_string);
auto &name = args[L"name"], &content = args[L"content"];
auto args = url.QueryParsed();
auto name = args.GetFirstValueByName(L"name");
auto content = args.GetFirstValueByName(L"content");
handler(std::format(L"{}: {}", name, content));

SendHttpJsonResponse(req_queue, req, 200, "OK", R"({"code": 0, "message": "ok"})");
Expand Down

0 comments on commit 53260ee

Please sign in to comment.