mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2025-12-19 05:30:06 +08:00
162 lines
6.9 KiB
C++
162 lines
6.9 KiB
C++
#include "include/configs/common/transport.h"
|
|
|
|
#include <QJsonArray>
|
|
#include <QUrlQuery>
|
|
#include <include/global/Utils.hpp>
|
|
#include <include/global/XhttpExtraConverter.hpp>
|
|
|
|
#include "include/configs/common/utils.h"
|
|
|
|
namespace Configs {
|
|
|
|
QString Transport::getHeadersString() {
|
|
QString result;
|
|
for (int i=0;i<headers.length();i+=2) {
|
|
result += headers[i]+"=";
|
|
result += "\""+headers[i+1]+"\" ";
|
|
}
|
|
return result;
|
|
}
|
|
|
|
QStringList Transport::getHeaderPairs(QString rawHeader) {
|
|
bool inQuote = false;
|
|
QString curr;
|
|
QStringList list;
|
|
for (const auto &ch: rawHeader) {
|
|
if (inQuote) {
|
|
if (ch == '"') {
|
|
inQuote = false;
|
|
list << curr;
|
|
curr = "";
|
|
continue;
|
|
} else {
|
|
curr += ch;
|
|
continue;
|
|
}
|
|
}
|
|
if (ch == '"') {
|
|
inQuote = true;
|
|
continue;
|
|
}
|
|
if (ch == ' ') {
|
|
if (!curr.isEmpty()) {
|
|
list << curr;
|
|
curr = "";
|
|
}
|
|
continue;
|
|
}
|
|
if (ch == '=') {
|
|
if (!curr.isEmpty()) {
|
|
list << curr;
|
|
curr = "";
|
|
}
|
|
continue;
|
|
}
|
|
curr+=ch;
|
|
}
|
|
if (!curr.isEmpty()) list<<curr;
|
|
|
|
return list;
|
|
}
|
|
|
|
bool Transport::ParseFromLink(const QString& link)
|
|
{
|
|
auto url = QUrl(link);
|
|
if (!url.isValid()) return false;
|
|
auto query = QUrlQuery(url.query(QUrl::ComponentFormattingOption::FullyDecoded));
|
|
|
|
if (query.hasQueryItem("type"))
|
|
{
|
|
type = query.queryItemValue("type");
|
|
if ((type == "tcp" && query.queryItemValue("headerType") == "http") || type == "h2") {
|
|
type = "http";
|
|
method = "GET";
|
|
}
|
|
}
|
|
if (query.hasQueryItem("host")) host = query.queryItemValue("host");
|
|
if (query.hasQueryItem("path")) path = query.queryItemValue("path");
|
|
if (query.hasQueryItem("method")) method = query.queryItemValue("method");
|
|
if (query.hasQueryItem("headers")) headers = query.queryItemValue("headers").split(",");
|
|
if (query.hasQueryItem("idle_timeout")) idle_timeout = query.queryItemValue("idle_timeout");
|
|
if (query.hasQueryItem("ping_timeout")) ping_timeout = query.queryItemValue("ping_timeout");
|
|
if (query.hasQueryItem("max_early_data")) max_early_data = query.queryItemValue("max_early_data").toInt();
|
|
if (query.hasQueryItem("early_data_header_name")) early_data_header_name = query.queryItemValue("early_data_header_name");
|
|
if (query.hasQueryItem("serviceName")) service_name = query.queryItemValue("serviceName");
|
|
if (query.hasQueryItem("mode")) xhttp_mode = query.queryItemValue("mode");
|
|
if (query.hasQueryItem("extra")) xhttp_extra = query.queryItemValue("extra");
|
|
return true;
|
|
}
|
|
bool Transport::ParseFromJson(const QJsonObject& object)
|
|
{
|
|
if (object.isEmpty()) return false;
|
|
if (object.contains("type")) type = object["type"].toString();
|
|
if (object.contains("host")) host = object["host"].toString();
|
|
if (object.contains("path")) path = object["path"].toString();
|
|
if (object.contains("method")) method = object["method"].toString();
|
|
if (object.contains("headers") && object["headers"].isObject()) {
|
|
headers = jsonObjectToQStringList(object["headers"].toObject());
|
|
}
|
|
if (object.contains("idle_timeout")) idle_timeout = object["idle_timeout"].toString();
|
|
if (object.contains("ping_timeout")) ping_timeout = object["ping_timeout"].toString();
|
|
if (object.contains("max_early_data")) max_early_data = object["max_early_data"].toInt();
|
|
if (object.contains("early_data_header_name")) early_data_header_name = object["early_data_header_name"].toString();
|
|
if (object.contains("service_name")) service_name = object["service_name"].toString();
|
|
if (object.contains("mode")) {
|
|
xhttp_mode = object["mode"].toString();
|
|
xhttp_extra = XhttpExtraConverter::singBoxToXray(object);
|
|
}
|
|
return true;
|
|
}
|
|
QString Transport::ExportToLink()
|
|
{
|
|
QUrlQuery query;
|
|
if (type.isEmpty() || type == "tcp") return "";
|
|
if (!type.isEmpty()) query.addQueryItem("type", type);
|
|
if (!host.isEmpty()) query.addQueryItem("host", host);
|
|
if (!path.isEmpty()) query.addQueryItem("path", path);
|
|
if (!method.isEmpty()) query.addQueryItem("method", method);
|
|
if (!headers.isEmpty()) query.addQueryItem("headers", headers.join(","));
|
|
if (!idle_timeout.isEmpty()) query.addQueryItem("idle_timeout", idle_timeout);
|
|
if (!ping_timeout.isEmpty()) query.addQueryItem("ping_timeout", ping_timeout);
|
|
if (max_early_data > 0) query.addQueryItem("max_early_data", QString::number(max_early_data));
|
|
if (!early_data_header_name.isEmpty()) query.addQueryItem("early_data_header_name", early_data_header_name);
|
|
if (!service_name.isEmpty()) query.addQueryItem("serviceName", service_name);
|
|
if (!xhttp_mode.isEmpty()) query.addQueryItem("mode", xhttp_mode);
|
|
if (!xhttp_extra.isEmpty()) query.addQueryItem("extra", xhttp_extra);
|
|
return query.toString();
|
|
}
|
|
QJsonObject Transport::ExportToJson()
|
|
{
|
|
QJsonObject object;
|
|
if (type.isEmpty() || type == "tcp") return object;
|
|
if (!type.isEmpty()) object["type"] = type;
|
|
if (!path.isEmpty()) object["path"] = path;
|
|
if (!method.isEmpty()) object["method"] = method;
|
|
if (!headers.isEmpty()) {
|
|
object["headers"] = qStringListToJsonObject(headers);
|
|
}
|
|
if (!host.isEmpty()) {
|
|
if (type == "http" || type == "httpupgrade") object["host"] = host;
|
|
if (type == "ws") {
|
|
auto headersObj = object["headers"].isObject() ? object["headers"].toObject() : QJsonObject();
|
|
headersObj["host"] = host;
|
|
object["headers"] = headersObj;
|
|
}
|
|
}
|
|
if (!idle_timeout.isEmpty()) object["idle_timeout"] = idle_timeout;
|
|
if (!ping_timeout.isEmpty()) object["ping_timeout"] = ping_timeout;
|
|
if (max_early_data > 0) object["max_early_data"] = max_early_data;
|
|
if (!early_data_header_name.isEmpty()) object["early_data_header_name"] = early_data_header_name;
|
|
if (!service_name.isEmpty()) object["service_name"] = service_name;
|
|
if (!xhttp_mode.isEmpty()) object["mode"] = xhttp_mode;
|
|
if (!xhttp_extra.isEmpty()) mergeJsonObjects(object, XhttpExtraConverter::xrayToSingBox(xhttp_extra));
|
|
return object;
|
|
}
|
|
BuildResult Transport::Build()
|
|
{
|
|
return {ExportToJson(), ""};
|
|
}
|
|
}
|
|
|
|
|