mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2025-12-23 01:22:18 +08:00
fix: Restore header type for compatiblity with Xray
This commit is contained in:
parent
ff15bc53a6
commit
26eefee4b9
@ -52,6 +52,15 @@ namespace NekoGui_fmt {
|
|||||||
transport["headers"] = QMapString2QJsonObject(headerMap);
|
transport["headers"] = QMapString2QJsonObject(headerMap);
|
||||||
}
|
}
|
||||||
outbound->insert("transport", transport);
|
outbound->insert("transport", transport);
|
||||||
|
} else if (header_type == "http") {
|
||||||
|
// TCP + headerType
|
||||||
|
QJsonObject transport{
|
||||||
|
{"type", "http"},
|
||||||
|
{"method", "GET"},
|
||||||
|
{"path", path},
|
||||||
|
{"headers", QJsonObject{{"Host", QListStr2QJsonArray(host.split(","))}}},
|
||||||
|
};
|
||||||
|
outbound->insert("transport", transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 对应字段 tls
|
// 对应字段 tls
|
||||||
|
|||||||
@ -60,6 +60,12 @@ namespace NekoGui_fmt {
|
|||||||
if (!stream->method.isEmpty()) query.addQueryItem("method", stream->method);
|
if (!stream->method.isEmpty()) query.addQueryItem("method", stream->method);
|
||||||
} else if (stream->network == "grpc") {
|
} else if (stream->network == "grpc") {
|
||||||
if (!stream->path.isEmpty()) query.addQueryItem("serviceName", stream->path);
|
if (!stream->path.isEmpty()) query.addQueryItem("serviceName", stream->path);
|
||||||
|
} else if (stream->network == "tcp") {
|
||||||
|
if (stream->header_type == "http") {
|
||||||
|
if (!stream->path.isEmpty()) query.addQueryItem("path", stream->path);
|
||||||
|
query.addQueryItem("headerType", "http");
|
||||||
|
query.addQueryItem("host", stream->host);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// mux
|
// mux
|
||||||
@ -156,6 +162,11 @@ namespace NekoGui_fmt {
|
|||||||
if (!stream->host.isEmpty()) query.addQueryItem("host", stream->host);
|
if (!stream->host.isEmpty()) query.addQueryItem("host", stream->host);
|
||||||
} else if (stream->network == "grpc") {
|
} else if (stream->network == "grpc") {
|
||||||
if (!stream->path.isEmpty()) query.addQueryItem("serviceName", stream->path);
|
if (!stream->path.isEmpty()) query.addQueryItem("serviceName", stream->path);
|
||||||
|
} else if (stream->network == "tcp") {
|
||||||
|
if (stream->header_type == "http") {
|
||||||
|
query.addQueryItem("headerType", "http");
|
||||||
|
query.addQueryItem("host", stream->host);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// mux
|
// mux
|
||||||
|
|||||||
@ -93,6 +93,12 @@ namespace NekoGui_fmt {
|
|||||||
stream->host = GetQueryValue(query, "host", "");
|
stream->host = GetQueryValue(query, "host", "");
|
||||||
} else if (stream->network == "grpc") {
|
} else if (stream->network == "grpc") {
|
||||||
stream->path = GetQueryValue(query, "serviceName", "");
|
stream->path = GetQueryValue(query, "serviceName", "");
|
||||||
|
} else if (stream->network == "tcp") {
|
||||||
|
if (GetQueryValue(query, "headerType") == "http") {
|
||||||
|
stream->header_type = "http";
|
||||||
|
stream->host = GetQueryValue(query, "host", "");
|
||||||
|
stream->path = GetQueryValue(query, "path", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// mux
|
// mux
|
||||||
@ -171,6 +177,7 @@ namespace NekoGui_fmt {
|
|||||||
stream->host = objN["host"].toString();
|
stream->host = objN["host"].toString();
|
||||||
stream->path = objN["path"].toString();
|
stream->path = objN["path"].toString();
|
||||||
stream->sni = objN["sni"].toString();
|
stream->sni = objN["sni"].toString();
|
||||||
|
stream->header_type = objN["type"].toString();
|
||||||
auto net = objN["net"].toString();
|
auto net = objN["net"].toString();
|
||||||
if (!net.isEmpty()) {
|
if (!net.isEmpty()) {
|
||||||
if (net == "h2") {
|
if (net == "h2") {
|
||||||
@ -239,6 +246,12 @@ namespace NekoGui_fmt {
|
|||||||
stream->host = GetQueryValue(query, "host", "");
|
stream->host = GetQueryValue(query, "host", "");
|
||||||
} else if (stream->network == "grpc") {
|
} else if (stream->network == "grpc") {
|
||||||
stream->path = GetQueryValue(query, "serviceName", "");
|
stream->path = GetQueryValue(query, "serviceName", "");
|
||||||
|
} else if (stream->network == "tcp") {
|
||||||
|
if (GetQueryValue(query, "headerType") == "http") {
|
||||||
|
stream->header_type = "http";
|
||||||
|
stream->path = GetQueryValue(query, "path", "");
|
||||||
|
stream->host = GetQueryValue(query, "host", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return !(uuid.isEmpty() || serverAddress.isEmpty());
|
return !(uuid.isEmpty() || serverAddress.isEmpty());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ namespace NekoGui_fmt {
|
|||||||
QString host = "";
|
QString host = "";
|
||||||
QString method = "";
|
QString method = "";
|
||||||
QString headers = "";
|
QString headers = "";
|
||||||
|
QString header_type = "";
|
||||||
|
|
||||||
QString sni = "";
|
QString sni = "";
|
||||||
QString alpn = "";
|
QString alpn = "";
|
||||||
@ -38,6 +39,7 @@ namespace NekoGui_fmt {
|
|||||||
_add(new configItem("cert", &certificate, itemType::string));
|
_add(new configItem("cert", &certificate, itemType::string));
|
||||||
_add(new configItem("insecure", &allow_insecure, itemType::boolean));
|
_add(new configItem("insecure", &allow_insecure, itemType::boolean));
|
||||||
_add(new configItem("headers", &headers, itemType::string));
|
_add(new configItem("headers", &headers, itemType::string));
|
||||||
|
_add(new configItem("h_type", &header_type, itemType::string));
|
||||||
_add(new configItem("method", &method, itemType::string));
|
_add(new configItem("method", &method, itemType::string));
|
||||||
_add(new configItem("ed_name", &ws_early_data_name, itemType::string));
|
_add(new configItem("ed_name", &ws_early_data_name, itemType::string));
|
||||||
_add(new configItem("ed_len", &ws_early_data_length, itemType::integer));
|
_add(new configItem("ed_len", &ws_early_data_length, itemType::integer));
|
||||||
|
|||||||
@ -459,6 +459,23 @@ namespace NekoGui_sub {
|
|||||||
}
|
}
|
||||||
bean->stream->path = Node2QString(h2["path"]);
|
bean->stream->path = Node2QString(h2["path"]);
|
||||||
}
|
}
|
||||||
|
auto tcp_http = NodeChild(proxy, {"http-opts", "http-opt"});
|
||||||
|
if (tcp_http.IsMap()) {
|
||||||
|
bean->stream->network = "tcp";
|
||||||
|
bean->stream->header_type = "http";
|
||||||
|
auto headers = tcp_http["headers"];
|
||||||
|
for (auto header: headers) {
|
||||||
|
if (Node2QString(header.first).toLower() == "host") {
|
||||||
|
bean->stream->host = Node2QString(header.second[0]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto paths = tcp_http["path"];
|
||||||
|
for (auto path: paths) {
|
||||||
|
bean->stream->path = Node2QString(path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (type == "hysteria") {
|
} else if (type == "hysteria") {
|
||||||
auto bean = ent->QUICBean();
|
auto bean = ent->QUICBean();
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,20 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
network_title_base = ui->network_box->title();
|
network_title_base = ui->network_box->title();
|
||||||
connect(ui->network, &QComboBox::currentTextChanged, this, [=](const QString &txt) {
|
connect(ui->network, &QComboBox::currentTextChanged, this, [=](const QString &txt) {
|
||||||
ui->network_box->setTitle(network_title_base.arg(txt));
|
ui->network_box->setTitle(network_title_base.arg(txt));
|
||||||
if (txt == "grpc") {
|
if (txt == "tcp") {
|
||||||
|
ui->header_type->setVisible(true);
|
||||||
|
ui->header_type_l->setVisible(true);
|
||||||
|
ui->headers->setVisible(false);
|
||||||
|
ui->headers_l->setVisible(false);
|
||||||
|
ui->method->setVisible(false);
|
||||||
|
ui->method_l->setVisible(false);
|
||||||
|
ui->path->setVisible(true);
|
||||||
|
ui->path_l->setVisible(true);
|
||||||
|
ui->host->setVisible(true);
|
||||||
|
ui->host_l->setVisible(true);
|
||||||
|
} else if (txt == "grpc") {
|
||||||
|
ui->header_type->setVisible(false);
|
||||||
|
ui->header_type_l->setVisible(false);
|
||||||
ui->headers->setVisible(false);
|
ui->headers->setVisible(false);
|
||||||
ui->headers_l->setVisible(false);
|
ui->headers_l->setVisible(false);
|
||||||
ui->method->setVisible(false);
|
ui->method->setVisible(false);
|
||||||
@ -42,6 +55,8 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
ui->host->setVisible(false);
|
ui->host->setVisible(false);
|
||||||
ui->host_l->setVisible(false);
|
ui->host_l->setVisible(false);
|
||||||
} else if (txt == "ws" || txt == "httpupgrade") {
|
} else if (txt == "ws" || txt == "httpupgrade") {
|
||||||
|
ui->header_type->setVisible(false);
|
||||||
|
ui->header_type_l->setVisible(false);
|
||||||
ui->headers->setVisible(true);
|
ui->headers->setVisible(true);
|
||||||
ui->headers_l->setVisible(true);
|
ui->headers_l->setVisible(true);
|
||||||
ui->method->setVisible(false);
|
ui->method->setVisible(false);
|
||||||
@ -51,6 +66,8 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
ui->host->setVisible(true);
|
ui->host->setVisible(true);
|
||||||
ui->host_l->setVisible(true);
|
ui->host_l->setVisible(true);
|
||||||
} else if (txt == "http") {
|
} else if (txt == "http") {
|
||||||
|
ui->header_type->setVisible(false);
|
||||||
|
ui->header_type_l->setVisible(false);
|
||||||
ui->headers->setVisible(true);
|
ui->headers->setVisible(true);
|
||||||
ui->headers_l->setVisible(true);
|
ui->headers_l->setVisible(true);
|
||||||
ui->method->setVisible(true);
|
ui->method->setVisible(true);
|
||||||
@ -60,6 +77,8 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
ui->host->setVisible(true);
|
ui->host->setVisible(true);
|
||||||
ui->host_l->setVisible(true);
|
ui->host_l->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
ui->header_type->setVisible(false);
|
||||||
|
ui->header_type_l->setVisible(false);
|
||||||
ui->headers->setVisible(false);
|
ui->headers->setVisible(false);
|
||||||
ui->headers_l->setVisible(false);
|
ui->headers_l->setVisible(false);
|
||||||
ui->method->setVisible(false);
|
ui->method->setVisible(false);
|
||||||
@ -236,7 +255,6 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
// 右边 stream
|
// 右边 stream
|
||||||
auto stream = GetStreamSettings(ent->bean.get());
|
auto stream = GetStreamSettings(ent->bean.get());
|
||||||
if (stream != nullptr) {
|
if (stream != nullptr) {
|
||||||
ui->network_box->setVisible(stream->network != "tcp");
|
|
||||||
ui->right_all_w->setVisible(true);
|
ui->right_all_w->setVisible(true);
|
||||||
ui->network->setCurrentText(stream->network);
|
ui->network->setCurrentText(stream->network);
|
||||||
ui->security->setCurrentText(stream->security);
|
ui->security->setCurrentText(stream->security);
|
||||||
@ -252,6 +270,7 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
ui->utlsFingerprint->setCurrentText(stream->utlsFingerprint);
|
ui->utlsFingerprint->setCurrentText(stream->utlsFingerprint);
|
||||||
}
|
}
|
||||||
ui->insecure->setChecked(stream->allow_insecure);
|
ui->insecure->setChecked(stream->allow_insecure);
|
||||||
|
ui->header_type->setCurrentText(stream->header_type);
|
||||||
ui->headers->setText(stream->headers);
|
ui->headers->setText(stream->headers);
|
||||||
ui->ws_early_data_name->setText(stream->ws_early_data_name);
|
ui->ws_early_data_name->setText(stream->ws_early_data_name);
|
||||||
ui->ws_early_data_length->setText(Int2String(stream->ws_early_data_length));
|
ui->ws_early_data_length->setText(Int2String(stream->ws_early_data_length));
|
||||||
@ -318,9 +337,11 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
if (type == "vmess" || type == "vless" || type == "trojan") {
|
if (type == "vmess" || type == "vless" || type == "trojan") {
|
||||||
ui->network_l->setVisible(true);
|
ui->network_l->setVisible(true);
|
||||||
ui->network->setVisible(true);
|
ui->network->setVisible(true);
|
||||||
|
ui->network_box->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
ui->network_l->setVisible(false);
|
ui->network_l->setVisible(false);
|
||||||
ui->network->setVisible(false);
|
ui->network->setVisible(false);
|
||||||
|
ui->network_box->setVisible(false);
|
||||||
}
|
}
|
||||||
if (type == "vmess" || type == "vless" || type == "trojan" || type == "http") {
|
if (type == "vmess" || type == "vless" || type == "trojan" || type == "http") {
|
||||||
ui->security->setVisible(true);
|
ui->security->setVisible(true);
|
||||||
@ -382,6 +403,7 @@ bool DialogEditProfile::onEnd() {
|
|||||||
stream->utlsFingerprint = ui->utlsFingerprint->currentText();
|
stream->utlsFingerprint = ui->utlsFingerprint->currentText();
|
||||||
stream->allow_insecure = ui->insecure->isChecked();
|
stream->allow_insecure = ui->insecure->isChecked();
|
||||||
stream->headers = ui->headers->text();
|
stream->headers = ui->headers->text();
|
||||||
|
stream->header_type = ui->header_type->currentText();
|
||||||
stream->method = ui->method->text();
|
stream->method = ui->method->text();
|
||||||
stream->ws_early_data_name = ui->ws_early_data_name->text();
|
stream->ws_early_data_name = ui->ws_early_data_name->text();
|
||||||
stream->ws_early_data_length = ui->ws_early_data_length->text().toInt();
|
stream->ws_early_data_length = ui->ws_early_data_length->text().toInt();
|
||||||
|
|||||||
@ -525,56 +525,14 @@
|
|||||||
<string>Network Settings (%1)</string>
|
<string>Network Settings (%1)</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="3" column="1">
|
<item row="6" column="0">
|
||||||
<widget class="MyLineEdit" name="host"/>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="MyLineEdit" name="ws_early_data_length"/>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="MyLineEdit" name="ws_early_data_name"/>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="host_l">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string notr="true"><html><head/><body><p>http host (ws/http/httpUpgrade)</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">Host</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="headers"/>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="ws_early_data_length_l">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">EarlyData Length</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="path_l">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string notr="true"><html><head/><body><p>http path (ws/http/httpUpgrade)</p><p>serviceName (gRPC)</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">Path</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QLabel" name="ws_early_data_name_l">
|
<widget class="QLabel" name="ws_early_data_name_l">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true">EarlyData Name</string>
|
<string notr="true">EarlyData Name</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="1" column="0">
|
||||||
<widget class="MyLineEdit" name="path"/>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="headers_l">
|
<widget class="QLabel" name="headers_l">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
@ -593,7 +551,39 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="ws_early_data_length_l">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">EarlyData Length</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="method"/>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="path_l">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string notr="true"><html><head/><body><p>http path (ws/http/httpUpgrade)</p><p>serviceName (gRPC)</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">Path</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="MyLineEdit" name="path"/>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="1">
|
||||||
|
<widget class="MyLineEdit" name="ws_early_data_name"/>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="MyLineEdit" name="ws_early_data_length"/>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="MyLineEdit" name="host"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="method_l">
|
<widget class="QLabel" name="method_l">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Method of http request, will be converted to uppercase</p></body></html></string>
|
<string><html><head/><body><p>Method of http request, will be converted to uppercase</p></body></html></string>
|
||||||
@ -603,8 +593,39 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="host_l">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string notr="true"><html><head/><body><p>http host (ws/http/httpUpgrade)</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">Host</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QLineEdit" name="method"/>
|
<widget class="QLineEdit" name="headers"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="header_type">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>http</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="header_type_l">
|
||||||
|
<property name="text">
|
||||||
|
<string>header type</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user