From 803f7db84ebf808e90e26556bf09308cec8e0b07 Mon Sep 17 00:00:00 2001 From: parhelia512 <0011d3@gmail.com> Date: Sat, 22 Nov 2025 01:13:25 +0800 Subject: [PATCH] Revert "fix: fix hysteria(2) url parser and generator for port hopping" This reverts commit d655b14f69d10b6e3b641e388d739d6f812ab0f3. --- 3rdparty/URLParser/url_parser.h | 96 ------------------------ 3rdparty/URLParser/url_parser_function.h | 47 ------------ src/configs/proxy/Bean2Link.cpp | 40 +++++----- src/configs/proxy/Link2Bean.cpp | 37 +++++---- 4 files changed, 34 insertions(+), 186 deletions(-) delete mode 100644 3rdparty/URLParser/url_parser.h delete mode 100644 3rdparty/URLParser/url_parser_function.h diff --git a/3rdparty/URLParser/url_parser.h b/3rdparty/URLParser/url_parser.h deleted file mode 100644 index d3625cd..0000000 --- a/3rdparty/URLParser/url_parser.h +++ /dev/null @@ -1,96 +0,0 @@ -// -// URL Parser for C++ -// Created Oct 22, 2017. -// Website : https://github.com/dongbum/URLParser -// Usage : Just include this header file. -// - -#pragma once - -#include -#include -#include - -#include "url_parser_function.h" - -class URLParser -{ -public: - struct HTTP_URL - { - std::string scheme; - std::string host; - std::string port; - std::vector path; - std::string query_string; - std::unordered_map query; - }; - -public: - static HTTP_URL Parse(const std::string& input_url) - { - HTTP_URL http_url; - - size_t st = 0; - size_t before = 0; - - URLParserFunction::FindKeyword(input_url, st, before, "://", http_url.scheme); - URLParserFunction::FindKeyword(input_url, st, before, "/", http_url.host); - - size_t temp_st = 0; - size_t temp_before = 0; - std::string temp_ip; - std::string temp_port; - - if (true == URLParserFunction::FindKeyword(http_url.host, temp_st, temp_before, ":", temp_ip)) - { - http_url.port = std::string(&http_url.host[temp_before]); - http_url.host = temp_ip; - } - - while (true) - { - std::string path; - if (false == URLParserFunction::FindKeyword(input_url, st, before, "/", path)) - break; - - http_url.path.push_back(path); - } - - std::string path; - if (false == URLParserFunction::FindKeyword(input_url, st, before, "?", path)) - { - path = std::string(&input_url[st + 1]); - http_url.path.push_back(path); - return http_url; - } - - if (st < input_url.length()) - { - http_url.query_string = std::string(&input_url[st + 1]); - if (false == http_url.query_string.empty()) - { - std::string query; - st = 0; - before = 0; - - while (true) - { - std::string key, value; - - if (false == URLParserFunction::FindKeyword(http_url.query_string, st, before, "&", query)) - { - URLParserFunction::SplitQueryString(std::string(&http_url.query_string[before]), "=", key, value); - http_url.query.insert(std::unordered_map::value_type(key, value)); - break; - } - - URLParserFunction::SplitQueryString(query, "=", key, value); - http_url.query.insert(std::unordered_map::value_type(key, value)); - } - } - } - - return http_url; - }; -}; diff --git a/3rdparty/URLParser/url_parser_function.h b/3rdparty/URLParser/url_parser_function.h deleted file mode 100644 index a8a6984..0000000 --- a/3rdparty/URLParser/url_parser_function.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include -#include - -class URLParserFunction -{ -public: - static bool FindKeyword(const std::string& input_url, size_t& st, size_t& before, const std::string& delim, std::string& result) - { - char temp[1024] = { 0, }; - size_t temp_st = st; - memcpy(&temp_st, &st, sizeof(temp_st)); - - st = input_url.find(delim, before); - if (st == std::string::npos) - { - st = temp_st; - return false; - } - - memcpy(&temp[0], &input_url[before], st - before); - before = st + delim.length(); - - result = std::string(temp); - if (result.empty()) - return false; - - return true; - }; - - static bool SplitQueryString(const std::string& str, const std::string& delim, std::string& key, std::string& value) - { - char first[1024] = { 0, }; - char second[1024] = { 0, }; - - size_t st = str.find(delim, 0); - - memcpy(first, &str[0], st); - memcpy(second, &str[st + 1], str.length() - st); - - key = std::string(first); - value = std::string(second); - - return true; - }; -}; diff --git a/src/configs/proxy/Bean2Link.cpp b/src/configs/proxy/Bean2Link.cpp index 362c1ca..638deb3 100644 --- a/src/configs/proxy/Bean2Link.cpp +++ b/src/configs/proxy/Bean2Link.cpp @@ -220,11 +220,10 @@ namespace Configs { QString QUICBean::ToShareLink() { QUrl url; - QString portRange; if (proxy_type == proxy_Hysteria) { url.setScheme("hysteria"); url.setHost(serverAddress); - url.setPort(0); + url.setPort(serverPort); QUrlQuery q; q.addQueryItem("upmbps", Int2String(uploadMbps)); q.addQueryItem("downmbps", Int2String(downloadMbps)); @@ -240,16 +239,15 @@ namespace Configs { if (!alpn.isEmpty()) q.addQueryItem("alpn", alpn); if (connectionReceiveWindow > 0) q.addQueryItem("recv_window", Int2String(connectionReceiveWindow)); if (streamReceiveWindow > 0) q.addQueryItem("recv_window_conn", Int2String(streamReceiveWindow)); - if (!serverPorts.empty()) { + if (!serverPorts.empty()) + { QStringList portList; - for (const auto& range : serverPorts) { - QString modifiedRange = range; - modifiedRange.replace(":", "-"); - portList.append(modifiedRange); + for (const auto& range : serverPorts) + { + portList.append(range.split(":")); } - portRange = portList.join(","); - } else - url.setPort(serverPort); + q.addQueryItem("server_ports", portList.join("-")); + } if (!hop_interval.isEmpty()) q.addQueryItem("hop_interval", hop_interval); if (!q.isEmpty()) url.setQuery(q); if (!name.isEmpty()) url.setFragment(name); @@ -272,7 +270,7 @@ namespace Configs { } else if (proxy_type == proxy_Hysteria2) { url.setScheme("hy2"); url.setHost(serverAddress); - url.setPort(0); + url.setPort(serverPort); if (password.contains(":")) { url.setUserName(SubStrBefore(password, ":")); url.setPassword(SubStrAfter(password, ":")); @@ -286,24 +284,20 @@ namespace Configs { } if (allowInsecure) q.addQueryItem("insecure", "1"); if (!sni.isEmpty()) q.addQueryItem("sni", sni); - if (!serverPorts.empty()) { + if (!serverPorts.empty()) + { QStringList portList; - for (const auto& range : serverPorts) { - QString modifiedRange = range; - modifiedRange.replace(":", "-"); - portList.append(modifiedRange); + for (const auto& range : serverPorts) + { + portList.append(range.split(":")); } - portRange = portList.join(","); - } else - url.setPort(serverPort); + q.addQueryItem("server_ports", portList.join("-")); + } if (!hop_interval.isEmpty()) q.addQueryItem("hop_interval", hop_interval); if (!q.isEmpty()) url.setQuery(q); if (!name.isEmpty()) url.setFragment(name); } - if (portRange.isEmpty()) - return url.toString(QUrl::FullyEncoded); - else - return url.toString(QUrl::FullyEncoded).replace(":0?", ":" + portRange + "?"); + return url.toString(QUrl::FullyEncoded); } QString WireguardBean::ToShareLink() { diff --git a/src/configs/proxy/Link2Bean.cpp b/src/configs/proxy/Link2Bean.cpp index dbe1f02..4551ef4 100644 --- a/src/configs/proxy/Link2Bean.cpp +++ b/src/configs/proxy/Link2Bean.cpp @@ -1,6 +1,5 @@ #include "include/dataStore/ProxyEntity.hpp" #include "include/configs/proxy/includes.h" -#include "3rdparty/URLParser/url_parser.h" #include @@ -303,16 +302,8 @@ namespace Configs { bool QUICBean::TryParseLink(const QString &link) { auto url = QUrl(link); - if (!url.isValid()) { - if(!url.errorString().startsWith("Invalid port")) - return false; - serverPort = 0; - serverPorts = QString::fromStdString(URLParser::Parse((link.split("?")[0] + "/").toStdString()).port).split(","); - for (auto & serverPort : serverPorts) { - serverPort.replace("-", ":"); - } - } auto query = QUrlQuery(url.query()); + if (url.host().isEmpty() || url.port() == -1) return false; if (url.scheme() == "hysteria") { // https://hysteria.network/docs/uri-scheme/ @@ -320,7 +311,7 @@ namespace Configs { name = url.fragment(QUrl::FullyDecoded); serverAddress = url.host(); - if (serverPort > 0) serverPort = url.port(); + serverPort = url.port(); obfsPassword = QUrl::fromPercentEncoding(query.queryItemValue("obfsParam").toUtf8()); allowInsecure = QStringList{"1", "true"}.contains(query.queryItemValue("insecure")); uploadMbps = query.queryItemValue("upmbps").toInt(); @@ -344,10 +335,13 @@ namespace Configs { connectionReceiveWindow = query.queryItemValue("recv_window").toInt(); streamReceiveWindow = query.queryItemValue("recv_window_conn").toInt(); - if (query.hasQueryItem("mport")) { - serverPorts = query.queryItemValue("mport").split(","); - for (int i=0; i < serverPorts.size(); i++) { - serverPorts[i].replace("-", ":"); + if (query.hasQueryItem("server_ports")) + { + auto portList = query.queryItemValue("server_ports").split("-"); + for (int i=0;i= portList.size()) break; + serverPorts += portList[i]+":"+portList[i+1]; } } hop_interval = query.queryItemValue("hop_interval"); @@ -372,7 +366,7 @@ namespace Configs { } else if (QStringList{"hy2", "hysteria2"}.contains(url.scheme())) { name = url.fragment(QUrl::FullyDecoded); serverAddress = url.host(); - if (serverPort > 0) serverPort = url.port(); + serverPort = url.port(); obfsPassword = QUrl::fromPercentEncoding(query.queryItemValue("obfs-password").toUtf8()); allowInsecure = QStringList{"1", "true"}.contains(query.queryItemValue("insecure")); @@ -381,10 +375,13 @@ namespace Configs { } else { password = url.userName() + ":" + url.password(); } - if (query.hasQueryItem("mport")) { - serverPorts = query.queryItemValue("mport").split(","); - for (int i=0; i < serverPorts.size(); i++) { - serverPorts[i].replace("-", ":"); + if (query.hasQueryItem("server_ports")) + { + auto portList = query.queryItemValue("server_ports").split("-"); + for (int i=0;i= portList.size()) break; + serverPorts += portList[i]+":"+portList[i+1]; } } hop_interval = query.queryItemValue("hop_interval");