Skip to content

Commit 35063db

Browse files
committed
Improvement share uri
1 parent 868c24b commit 35063db

File tree

8 files changed

+136
-235
lines changed

8 files changed

+136
-235
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package com.v2ray.ang.util.fmt
2+
3+
import android.text.TextUtils
4+
import com.v2ray.ang.dto.V2rayConfig
5+
import com.v2ray.ang.util.Utils
6+
7+
open class FmtBase {
8+
fun toUri(address: String?, port: Int?, userInfo: String?, dicQuery: HashMap<String, String>?, remark: String): String {
9+
val query = if (dicQuery != null)
10+
("?" + dicQuery.toList().joinToString(
11+
separator = "&",
12+
transform = { it.first + "=" + Utils.urlEncode(it.second) }))
13+
else ""
14+
15+
val url = String.format(
16+
"%s@%s:%s",
17+
Utils.urlEncode(userInfo ?: ""),
18+
Utils.getIpv6Address(address),
19+
port
20+
)
21+
22+
return "${url}${query}#${Utils.urlEncode(remark)}"
23+
}
24+
25+
fun getStdTransport(outbound: V2rayConfig.OutboundBean, streamSetting: V2rayConfig.OutboundBean.StreamSettingsBean): HashMap<String, String> {
26+
val dicQuery = HashMap<String, String>()
27+
28+
dicQuery["security"] = streamSetting.security.ifEmpty { "none" }
29+
(streamSetting.tlsSettings
30+
?: streamSetting.realitySettings)?.let { tlsSetting ->
31+
if (!TextUtils.isEmpty(tlsSetting.serverName)) {
32+
dicQuery["sni"] = tlsSetting.serverName
33+
}
34+
if (!tlsSetting.alpn.isNullOrEmpty() && tlsSetting.alpn.isNotEmpty()) {
35+
dicQuery["alpn"] =
36+
Utils.removeWhiteSpace(tlsSetting.alpn.joinToString(",")).orEmpty()
37+
}
38+
if (!TextUtils.isEmpty(tlsSetting.fingerprint)) {
39+
dicQuery["fp"] = tlsSetting.fingerprint.orEmpty()
40+
}
41+
if (!TextUtils.isEmpty(tlsSetting.publicKey)) {
42+
dicQuery["pbk"] = tlsSetting.publicKey.orEmpty()
43+
}
44+
if (!TextUtils.isEmpty(tlsSetting.shortId)) {
45+
dicQuery["sid"] = tlsSetting.shortId.orEmpty()
46+
}
47+
if (!TextUtils.isEmpty(tlsSetting.spiderX)) {
48+
dicQuery["spx"] = tlsSetting.spiderX.orEmpty()
49+
}
50+
}
51+
dicQuery["type"] =
52+
streamSetting.network.ifEmpty { V2rayConfig.DEFAULT_NETWORK }
53+
54+
outbound.getTransportSettingDetails()?.let { transportDetails ->
55+
when (streamSetting.network) {
56+
"tcp" -> {
57+
dicQuery["headerType"] = transportDetails[0].ifEmpty { "none" }
58+
if (!TextUtils.isEmpty(transportDetails[1])) {
59+
dicQuery["host"] = transportDetails[1]
60+
}
61+
}
62+
63+
"kcp" -> {
64+
dicQuery["headerType"] = transportDetails[0].ifEmpty { "none" }
65+
if (!TextUtils.isEmpty(transportDetails[2])) {
66+
dicQuery["seed"] = transportDetails[2]
67+
}
68+
}
69+
70+
"ws", "httpupgrade", "splithttp" -> {
71+
if (!TextUtils.isEmpty(transportDetails[1])) {
72+
dicQuery["host"] = transportDetails[1]
73+
}
74+
if (!TextUtils.isEmpty(transportDetails[2])) {
75+
dicQuery["path"] = transportDetails[2]
76+
}
77+
}
78+
79+
"http", "h2" -> {
80+
dicQuery["type"] = "http"
81+
if (!TextUtils.isEmpty(transportDetails[1])) {
82+
dicQuery["host"] = transportDetails[1]
83+
}
84+
if (!TextUtils.isEmpty(transportDetails[2])) {
85+
dicQuery["path"] = transportDetails[2]
86+
}
87+
}
88+
89+
"quic" -> {
90+
dicQuery["headerType"] = transportDetails[0].ifEmpty { "none" }
91+
dicQuery["quicSecurity"] = transportDetails[1]
92+
dicQuery["key"] = transportDetails[2]
93+
}
94+
95+
"grpc" -> {
96+
dicQuery["mode"] = transportDetails[0]
97+
dicQuery["authority"] = transportDetails[1]
98+
dicQuery["serviceName"] = transportDetails[2]
99+
}
100+
}
101+
}
102+
return dicQuery
103+
}
104+
}

V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/fmt/Hysteria2Fmt.kt

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import com.v2ray.ang.util.MmkvManager.settingsStorage
1212
import com.v2ray.ang.util.Utils
1313
import java.net.URI
1414

15-
object Hysteria2Fmt {
15+
object Hysteria2Fmt : FmtBase() {
1616

1717
fun parse(str: String): ServerConfig {
1818
var allowInsecure = settingsStorage?.decodeBool(AppConfig.PREF_ALLOW_INSECURE) ?: false
@@ -51,7 +51,7 @@ object Hysteria2Fmt {
5151
val outbound = config.getProxyOutbound() ?: return ""
5252
val streamSetting = outbound.streamSettings ?: V2rayConfig.OutboundBean.StreamSettingsBean()
5353

54-
val remark = "#" + Utils.urlEncode(config.remarks)
54+
5555
val dicQuery = HashMap<String, String>()
5656
dicQuery["security"] = streamSetting.security.ifEmpty { "none" }
5757
streamSetting.tlsSettings?.let { tlsSetting ->
@@ -68,17 +68,7 @@ object Hysteria2Fmt {
6868
dicQuery["obfs-password"] = outbound.settings?.obfsPassword ?: ""
6969
}
7070

71-
val query = "?" + dicQuery.toList().joinToString(
72-
separator = "&",
73-
transform = { it.first + "=" + it.second })
74-
75-
val url = String.format(
76-
"%s@%s:%s",
77-
outbound.getPassword(),
78-
Utils.getIpv6Address(outbound.getServerAddress()),
79-
outbound.getServerPort()
80-
)
81-
return url + query + remark
71+
return toUri(outbound.getServerAddress(), outbound.getServerPort(), outbound.getPassword(), dicQuery, config.remarks)
8272
}
8373

8474
fun toNativeConfig(config: ServerConfig, socksPort: Int): Hysteria2Bean? {

V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/fmt/ShadowsocksFmt.kt

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import com.v2ray.ang.extension.idnHost
88
import com.v2ray.ang.util.Utils
99
import java.net.URI
1010

11-
object ShadowsocksFmt {
11+
object ShadowsocksFmt : FmtBase() {
1212
fun parse(str: String): ServerConfig? {
1313
val config = ServerConfig.create(EConfigType.SHADOWSOCKS)
1414
if (!tryResolveResolveSip002(str, config)) {
@@ -52,16 +52,10 @@ object ShadowsocksFmt {
5252

5353
fun toUri(config: ServerConfig): String {
5454
val outbound = config.getProxyOutbound() ?: return ""
55-
val remark = "#" + Utils.urlEncode(config.remarks)
56-
val pw =
57-
Utils.encode("${outbound.getSecurityEncryption()}:${outbound.getPassword()}")
58-
val url = String.format(
59-
"%s@%s:%s",
60-
pw,
61-
Utils.getIpv6Address(outbound.getServerAddress()),
62-
outbound.getServerPort()
63-
)
64-
return url + remark
55+
56+
val pw = Utils.encode("${outbound.getSecurityEncryption()}:${outbound.getPassword()}")
57+
58+
return toUri(outbound.getServerAddress(), outbound.getServerPort(), pw, null, config.remarks)
6559
}
6660

6761
private fun tryResolveResolveSip002(str: String, config: ServerConfig): Boolean {

V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/fmt/SocksFmt.kt

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import com.v2ray.ang.dto.ServerConfig
55
import com.v2ray.ang.dto.V2rayConfig
66
import com.v2ray.ang.util.Utils
77

8-
object SocksFmt {
8+
object SocksFmt : FmtBase() {
99
fun parse(str: String): ServerConfig? {
1010
val config = ServerConfig.create(EConfigType.SOCKS)
1111
var result = str.replace(EConfigType.SOCKS.protocolScheme, "")
@@ -52,18 +52,13 @@ object SocksFmt {
5252

5353
fun toUri(config: ServerConfig): String {
5454
val outbound = config.getProxyOutbound() ?: return ""
55-
val remark = "#" + Utils.urlEncode(config.remarks)
55+
5656
val pw =
5757
if (outbound.settings?.servers?.get(0)?.users?.get(0)?.user != null)
5858
"${outbound.settings?.servers?.get(0)?.users?.get(0)?.user}:${outbound.getPassword()}"
5959
else
6060
":"
61-
val url = String.format(
62-
"%s@%s:%s",
63-
Utils.encode(pw),
64-
Utils.getIpv6Address(outbound.getServerAddress()),
65-
outbound.getServerPort()
66-
)
67-
return url + remark
61+
62+
return toUri(outbound.getServerAddress(), outbound.getServerPort(), pw, null, config.remarks)
6863
}
6964
}

V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/fmt/TrojanFmt.kt

Lines changed: 5 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import com.v2ray.ang.util.MmkvManager.settingsStorage
1010
import com.v2ray.ang.util.Utils
1111
import java.net.URI
1212

13-
object TrojanFmt {
13+
object TrojanFmt : FmtBase() {
1414

1515
fun parse(str: String): ServerConfig {
1616
var allowInsecure = settingsStorage?.decodeBool(AppConfig.PREF_ALLOW_INSECURE) ?: false
@@ -76,98 +76,15 @@ object TrojanFmt {
7676
val outbound = config.getProxyOutbound() ?: return ""
7777
val streamSetting = outbound.streamSettings ?: V2rayConfig.OutboundBean.StreamSettingsBean()
7878

79-
val remark = "#" + Utils.urlEncode(config.remarks)
80-
val dicQuery = HashMap<String, String>()
79+
80+
val dicQuery = getStdTransport(outbound, streamSetting)
81+
8182
config.outboundBean?.settings?.servers?.get(0)?.flow?.let {
8283
if (!TextUtils.isEmpty(it)) {
8384
dicQuery["flow"] = it
8485
}
8586
}
8687

87-
dicQuery["security"] = streamSetting.security.ifEmpty { "none" }
88-
(streamSetting.tlsSettings
89-
?: streamSetting.realitySettings)?.let { tlsSetting ->
90-
if (!TextUtils.isEmpty(tlsSetting.serverName)) {
91-
dicQuery["sni"] = tlsSetting.serverName
92-
}
93-
if (!tlsSetting.alpn.isNullOrEmpty() && tlsSetting.alpn.isNotEmpty()) {
94-
dicQuery["alpn"] =
95-
Utils.removeWhiteSpace(tlsSetting.alpn.joinToString(",")).orEmpty()
96-
}
97-
if (!TextUtils.isEmpty(tlsSetting.fingerprint)) {
98-
dicQuery["fp"] = tlsSetting.fingerprint.orEmpty()
99-
}
100-
if (!TextUtils.isEmpty(tlsSetting.publicKey)) {
101-
dicQuery["pbk"] = tlsSetting.publicKey.orEmpty()
102-
}
103-
if (!TextUtils.isEmpty(tlsSetting.shortId)) {
104-
dicQuery["sid"] = tlsSetting.shortId.orEmpty()
105-
}
106-
if (!TextUtils.isEmpty(tlsSetting.spiderX)) {
107-
dicQuery["spx"] = Utils.urlEncode(tlsSetting.spiderX.orEmpty())
108-
}
109-
}
110-
dicQuery["type"] =
111-
streamSetting.network.ifEmpty { V2rayConfig.DEFAULT_NETWORK }
112-
113-
outbound.getTransportSettingDetails()?.let { transportDetails ->
114-
when (streamSetting.network) {
115-
"tcp" -> {
116-
dicQuery["headerType"] = transportDetails[0].ifEmpty { "none" }
117-
if (!TextUtils.isEmpty(transportDetails[1])) {
118-
dicQuery["host"] = Utils.urlEncode(transportDetails[1])
119-
}
120-
}
121-
122-
"kcp" -> {
123-
dicQuery["headerType"] = transportDetails[0].ifEmpty { "none" }
124-
if (!TextUtils.isEmpty(transportDetails[2])) {
125-
dicQuery["seed"] = Utils.urlEncode(transportDetails[2])
126-
}
127-
}
128-
129-
"ws", "httpupgrade", "splithttp" -> {
130-
if (!TextUtils.isEmpty(transportDetails[1])) {
131-
dicQuery["host"] = Utils.urlEncode(transportDetails[1])
132-
}
133-
if (!TextUtils.isEmpty(transportDetails[2])) {
134-
dicQuery["path"] = Utils.urlEncode(transportDetails[2])
135-
}
136-
}
137-
138-
"http", "h2" -> {
139-
dicQuery["type"] = "http"
140-
if (!TextUtils.isEmpty(transportDetails[1])) {
141-
dicQuery["host"] = Utils.urlEncode(transportDetails[1])
142-
}
143-
if (!TextUtils.isEmpty(transportDetails[2])) {
144-
dicQuery["path"] = Utils.urlEncode(transportDetails[2])
145-
}
146-
}
147-
148-
"quic" -> {
149-
dicQuery["headerType"] = transportDetails[0].ifEmpty { "none" }
150-
dicQuery["quicSecurity"] = Utils.urlEncode(transportDetails[1])
151-
dicQuery["key"] = Utils.urlEncode(transportDetails[2])
152-
}
153-
154-
"grpc" -> {
155-
dicQuery["mode"] = transportDetails[0]
156-
dicQuery["authority"] = Utils.urlEncode(transportDetails[1])
157-
dicQuery["serviceName"] = Utils.urlEncode(transportDetails[2])
158-
}
159-
}
160-
}
161-
val query = "?" + dicQuery.toList().joinToString(
162-
separator = "&",
163-
transform = { it.first + "=" + it.second })
164-
165-
val url = String.format(
166-
"%s@%s:%s",
167-
outbound.getPassword(),
168-
Utils.getIpv6Address(outbound.getServerAddress()),
169-
outbound.getServerPort()
170-
)
171-
return url + query + remark
88+
return toUri(outbound.getServerAddress(), outbound.getServerPort(), outbound.getPassword(), dicQuery, config.remarks)
17289
}
17390
}

0 commit comments

Comments
 (0)