Skip to content

Commit

Permalink
luci-app-ssr-plus: Add Xray new version XHTTP transport (formerly `…
Browse files Browse the repository at this point in the history
…SplitHTTP` transport) support.

See: XTLS/Xray-core#4113

说明:本次新增的 `XHTTP` 传输协议,在使用新版本的Xray情况下,可将旧版本节点的 `SplitHTTP` 传输协议修改为新版本的 `XHTTP` 传输协议,但旧版本的Xray只能使用 `SplitHTTP` 传输协议,因此暂不删除旧版本的`SplitHTTP` 传输协议支持。
  • Loading branch information
zxlhhyccc committed Jan 12, 2025
1 parent 1869e7f commit 3c5883a
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 15 deletions.
6 changes: 3 additions & 3 deletions luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,12 @@ for key, server_type in pairs(type_table) do
end

-- Socks User
o = s:option(Value, "socks5_user", translate("Socks5 User"), translate("Only when auth is password valid, Mandatory."))
o = s:option(Value, "socks5_user", translate("Socks5 User"), translate("Only when Socks5 Auth Mode is password valid, Mandatory."))
o.rmempty = true
o:depends("socks5_auth", "password")

-- Socks Password
o = s:option(Value, "socks5_pass", translate("Socks5 Password"), translate("Only when auth is password valid, Not mandatory."))
o = s:option(Value, "socks5_pass", translate("Socks5 Password"), translate("Only when Socks5 Auth Mode is password valid, Not mandatory."))
o.password = true
o.rmempty = true
o:depends("socks5_auth", "password")
Expand Down Expand Up @@ -263,7 +263,7 @@ o.default = 0
s = m:section(TypedSection, "xray_noise_packets", translate("Xray Noise Packets"))
s.description = translate(
"<font style='color:red'>" .. translate("To send noise packets, select \"Noise\" in Xray Settings.") .. "</font>" ..
"<br/><font><b>" .. translate("For specific usage, see: ") .. "</b></font>" ..
"<br/><font><b>" .. translate("For specific usage, see:") .. "</b></font>" ..
"<a href='https://xtls.github.io/config/outbounds/freedom.html' target='_blank'>" ..
"<font style='color:green'><b>" .. translate("Click to the page") .. "</b></font></a>")
s.template = "cbi/tblsection"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require "nixio.fs"
require "luci.sys"
require "luci.http"
require "luci.jsonc"
require "luci.model.ipkg"

local m, s, o
Expand Down Expand Up @@ -504,7 +505,6 @@ o.rmempty = true
o.default = ""
o:depends("type", "tuic")


o = s:option(ListValue, "udp_relay_mode", translate("UDP relay mode"))
o:depends("type", "tuic")
o:value("native", translate("native UDP characteristics"))
Expand Down Expand Up @@ -623,6 +623,7 @@ o:value("kcp", "mKCP")
o:value("ws", "WebSocket")
o:value("httpupgrade", "HTTPUpgrade")
o:value("splithttp", "SplitHTTP")
o:value("xhttp", "XHTTP")
o:value("h2", "HTTP/2")
o:value("quic", "QUIC")
o:value("grpc", "gRPC")
Expand Down Expand Up @@ -703,6 +704,78 @@ o = s:option(Value, "splithttp_path", translate("Splithttp Path"))
o:depends("transport", "splithttp")
o.rmempty = true

-- [[ XHTTP部分 ]]--
o = s:option(ListValue, "xhttp_alpn", translate("XHTTP Alpn"))
o.default = ""
o:value("", translate("Default"))
o:value("h3")
o:value("h2")
o:value("h3,h2")
o:value("http/1.1")
o:value("h2,http/1.1")
o:value("h3,h2,http/1.1")
o:depends("transport", "xhttp")

o = s:option(ListValue, "xhttp_mode", translate("XHTTP Mode"))
o:depends("transport", "xhttp")
o.default = "auto"
o:value("auto")
o:value("packet-up")
o:value("stream-up")
o:value("stream-one")

o = s:option(Value, "xhttp_host", translate("XHTTP Host"))
o:depends({transport = "xhttp", tls = false})
o.rmempty = true

o = s:option(Value, "xhttp_path", translate("XHTTP Path"))
o.placeholder = "/"
o:depends("transport", "xhttp")
o.rmempty = true

o = s:option(Flag, "enable_xhttp_extra", translate("XHTTP Extra"))
o.description = translate("Enable this option to configure XHTTP Extra (JSON format).")
o.default = "0"
o.rmempty = false
o:depends("transport", "xhttp")

o = s:option(TextValue, "xhttp_extra", " ")
o.description = translate(
"<font><b>" .. translate("Configure XHTTP Extra Settings (JSON format), see:") .. "</b></font>" ..
" <a href='https://xtls.github.io/config/transports/splithttp.html#extra' target='_blank'>" ..
"<font style='color:green'><b>" .. translate("Click to the page") .. "</b></font></a>")
o:depends("enable_xhttp_extra", true)
o.rmempty = true
o.rows = 10
o.wrap = "off"
o.custom_write = function(self, section, value)
m:set(section, "xhttp_extra", value)
local success, data = pcall(luci.jsonc.parse, value)
if success and data then
local address = (data.extra and data.extra.downloadSettings and data.extra.downloadSettings.address)
or (data.downloadSettings and data.downloadSettings.address)
if address and address ~= "" then
m:set(section, "download_address", address)
else
m:del(section, "download_address")
end
else
m:del(section, "download_address")
end
end
o.validate = function(self, value)
value = value:gsub("\r\n", "\n"):gsub("^[ \t]*\n", ""):gsub("\n[ \t]*$", ""):gsub("\n[ \t]*\n", "\n")
if value:sub(-1) == "\n" then
value = value:sub(1, -2)
end
local success, data = pcall(luci.jsonc.parse, value)
if not success or not data then
return nil, translate("Invalid JSON format")
end

return value
end

-- [[ H2部分 ]]--

-- H2域名
Expand Down
36 changes: 36 additions & 0 deletions luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,18 @@
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.splithttp_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
break;
case "xhttp":
if (params.get("security") !== "tls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_mode')[0].value = params.get("mode") || "auto";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
if (params.get("extra") && params.get("extra").trim() !== "") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].checked = true; // 设置 enable_xhttp_extra 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_extra')[0].value = params.get("extra") || "";
}
break;
case "kcp":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.kcp_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.seed')[0].value = params.get("seed") || "";
Expand Down Expand Up @@ -338,6 +350,16 @@
document.getElementsByName('cbid.shadowsocksr.' + sid + '.splithttp_host')[0].value = ssm.host;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.splithttp_path')[0].value = ssm.path;
}
if (ssm.net == "xhttp") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_mode')[0].value = ssm.mode;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_host')[0].value = ssm.host;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_path')[0].value = ssm.path;
if (params.get("extra") && params.get("extra").trim() !== "") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].checked = true; // 设置 enable_xhttp_extra 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_extra')[0].value = ssm.extra;
}
}
if (ssm.net == "h2") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_host')[0].value = ssm.host;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_path')[0].value = ssm.path;
Expand All @@ -352,6 +374,7 @@
if (ssm.tls == "tls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_alpn')[0].value = ssm.alpn;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = ssm.sni || ssm.host;
}
if (ssm.mux !== undefined) {
Expand Down Expand Up @@ -412,6 +435,7 @@
setElementValue('cbid.shadowsocksr.' + sid + '.tls_flow', params.get("flow") || "none");
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.tls_flow', event);

setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_alpn', params.get("alpn") || "");
setElementValue('cbid.shadowsocksr.' + sid + '.fingerprint', params.get("fp") || "");
setElementValue('cbid.shadowsocksr.' + sid + '.tls_host', params.get("sni") || "");
}
Expand All @@ -434,6 +458,18 @@
}
setElementValue('cbid.shadowsocksr.' + sid + '.splithttp_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
break;
case "xhttp":
if (params.get("security") !== "tls") {
setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
}
setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_mode', params.get("mode") || "auto");
setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
if (params.get("extra") && params.get("extra").trim() !== "") {
setElementValue('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra', true); // 设置 enable_xhttp_extra 为 true
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra', event); // 触发事件
setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_extra', params.get("extra") || "");
}
break;
case "kcp":
setElementValue('cbid.shadowsocksr.' + sid + '.kcp_guise', params.get("headerType") || "none");
setElementValue('cbid.shadowsocksr.' + sid + '.seed', params.get("seed") || "");
Expand Down
33 changes: 27 additions & 6 deletions luci-app-ssr-plus/po/zh_Hans/ssr-plus.po
Original file line number Diff line number Diff line change
Expand Up @@ -901,14 +901,14 @@ msgstr "Socks 协议的认证方式,默认值:noauth。"
msgid "Socks5 User"
msgstr "Socks5 用户名"

msgid "Only when auth is password valid, Mandatory."
msgstr "仅当 auth 为 password 时有效,必填。"
msgid "Only when Socks5 Auth Mode is password valid, Mandatory."
msgstr "仅当 Socks5 认证方式为 Password 时有效,必填。"

msgid "Socks5 Password"
msgstr "Socks5 密码"

msgid "Only when auth is password valid, Not mandatory."
msgstr "仅当 auth 为 password 时有效,非必填。"
msgid "Only when Socks5 Auth Mode is password valid, Not mandatory."
msgstr "仅当 Socks5 认证方式为 Password 时有效,非必填。"

msgid "Enabled Mixed"
msgstr "启用 Mixed"
Expand Down Expand Up @@ -952,8 +952,8 @@ msgstr "UDP 噪声,在某些情况下可以绕过一些针对 UDP 协议的限
msgid "To send noise packets, select \"Noise\" in Xray Settings."
msgstr "在 Xray 设置中勾选 “噪声” 以发送噪声包。"

msgid "For specific usage, see: "
msgstr "具体使用方法参见:"
msgid "For specific usage, see:"
msgstr "具体使用方法,请参见:"

msgid "Click to the page"
msgstr "点击前往"
Expand Down Expand Up @@ -1018,6 +1018,27 @@ msgstr "SplitHTTP 主机名"
msgid "Splithttp Path"
msgstr "SplitHTTP 路径"

msgid "XHTTP Mode"
msgstr "XHTTP 模式"

msgid "XHTTP Host"
msgstr "XHTTP 主机名"

msgid "XHTTP Path"
msgstr "XHTTP 路径"

msgid "XHTTP Extra"
msgstr "XHTTP 附加项"

msgid "Enable this option to configure XHTTP Extra (JSON format)."
msgstr "启用此选项配置 XHTTP 附加项(JSON 格式)。"

msgid "Configure XHTTP Extra Settings (JSON format), see:"
msgstr "配置 XHTTP 额外设置(JSON 格式),请参见:"

msgid "Invalid JSON format"
msgstr "无效的 JSON 格式"

msgid "HTTP/2 Host"
msgstr "HTTP/2 主机名"

Expand Down
25 changes: 20 additions & 5 deletions luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ local ucursor = require "luci.model.uci".cursor()
local json = require "luci.jsonc"

local server_section = arg[1]
local proto = arg[2]
local proto = arg[2] or "tcp"
local local_port = arg[3] or "0"
local socks_port = arg[4] or "0"

Expand Down Expand Up @@ -179,7 +179,7 @@ end

-- 开启 socks 代理
-- 检查是否启用 socks 代理
if proto:find("tcp") and socks_port ~= "0" then
if proto and proto:find("tcp") and socks_port ~= "0" then
table.insert(Xray.inbounds, {
-- socks
protocol = "socks",
Expand Down Expand Up @@ -209,7 +209,7 @@ end
security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or (server.reality == '1') and "reality" or nil,
tlsSettings = (server.tls == '1') and {
-- tls
alpn = server.tls_alpn,
alpn = (server.transport == "xhttp" and server.xhttp_alpn ~= "") and server.xhttp_alpn or server.tls_alpn,
fingerprint = server.fingerprint,
allowInsecure = (server.insecure == "1"),
serverName = server.tls_host,
Expand All @@ -225,6 +225,7 @@ end
minVersion = "1.3"
} or nil,
realitySettings = (server.reality == '1') and {
alpn = (server.transport == "xhttp" and server.xhttp_alpn ~= "") and server.xhttp_alpn or nil,
publicKey = server.reality_publickey,
shortId = server.reality_shortid,
spiderX = server.reality_spiderx,
Expand Down Expand Up @@ -271,6 +272,20 @@ end
host = (server.splithttp_host or server.tls_host) or nil,
path = server.splithttp_path or "/"
} or nil,
xhttpSettings = (server.transport == "xhttp") and {
-- xhttp
mode = server.xhttp_mode or "auto",
host = (server.xhttp_host or server.tls_host) or nil,
path = server.xhttp_path or "/",
extra = (server.enable_xhttp_extra == "1" and server.xhttp_extra) and (function()
local success, parsed = pcall(json.parse, server.xhttp_extra)
if success then
return parsed.extra or parsed
else
return nil
end
end)() or nil
} or nil,
httpSettings = (server.transport == "h2") and {
-- h2
path = server.h2_path or "",
Expand Down Expand Up @@ -387,15 +402,15 @@ local ss = {
server_port = tonumber(server.server_port),
local_address = "0.0.0.0",
local_port = tonumber(local_port),
mode = (proto == "tcp,udp") and "tcp_and_udp" or proto .. "_only",
mode = (proto == "tcp,udp") and "tcp_and_udp" or (proto .. "_only"),
password = server.password,
method = server.encrypt_method_ss,
timeout = tonumber(server.timeout),
fast_open = (server.fast_open == "1") and true or false,
reuse_port = true
}
local hysteria = {
server = (server.server_port and (server.port_range and (server.server .. ":" .. server.server_port .. "," .. server.port_range) or server.server .. ":" .. server.server_port) or (server.port_range and server.server .. ":" .. server.port_range or server.server .. ":443")),
server = (server.server_port and (server.port_range and (server.server .. ":" .. server.server_port .. "," .. server.port_range) or (server.server .. ":" .. server.server_port) or (server.port_range and server.server .. ":" .. server.port_range or server.server .. ":443"))),
bandwidth = (server.uplink_capacity or server.downlink_capacity) and {
up = tonumber(server.uplink_capacity) and tonumber(server.uplink_capacity) .. " mbps" or nil,
down = tonumber(server.downlink_capacity) and tonumber(server.downlink_capacity) .. " mbps" or nil
Expand Down
Loading

0 comments on commit 3c5883a

Please sign in to comment.