mirror of
https://github.com/shadowsocks/ShadowsocksX-NG.git
synced 2026-11-13 17:43:45 +00:00
74 lines
2.6 KiB
Swift
74 lines
2.6 KiB
Swift
import Foundation
|
|
|
|
/// 叶子预检:一次完成激活阻塞判定与凭据/插件解析。插件参数保持 opaque,不
|
|
/// 在此判断其语法或远端握手;空 issues 只表示没有已知的本地激活阻塞原因。
|
|
/// 已解析事实供运行时文档装配复用,目录树只取 `invalidReasons`。
|
|
///
|
|
/// 不变量:`issues` 为空 ⇒ `password` 非空;`pluginProgram` 存在且无
|
|
/// `pluginNotProvided` ⇒ `plugin` 非空。
|
|
struct LeafPreparation: Equatable, Sendable {
|
|
let issues: [LeafInvalidationReason]
|
|
let password: String?
|
|
let plugin: ResolvedPlugin?
|
|
let pluginOptions: String?
|
|
|
|
/// 运行时装配入口:一次解析并给出全部阻塞原因与已解析事实。
|
|
static func prepare(
|
|
_ fields: ServerFields,
|
|
plugins: PluginExecutableResolving
|
|
) -> LeafPreparation {
|
|
var issues: [LeafInvalidationReason] = []
|
|
appendAddressIssue(fields.address, to: &issues)
|
|
appendPortIssue(fields.port, to: &issues)
|
|
appendMethodIssue(fields.encryptionMethod, to: &issues)
|
|
|
|
let password = fields.password.isEmpty ? nil : fields.password
|
|
if password == nil { issues.append(.missingPassword) }
|
|
var plugin: ResolvedPlugin?
|
|
var pluginOptions: String?
|
|
if let program = fields.pluginProgram {
|
|
if let resolved = plugins.resolve(program: program) {
|
|
plugin = resolved
|
|
} else {
|
|
issues.append(.pluginNotProvided(program: program))
|
|
}
|
|
pluginOptions = fields.pluginOptions
|
|
}
|
|
return LeafPreparation(
|
|
issues: issues, password: password, plugin: plugin, pluginOptions: pluginOptions)
|
|
}
|
|
|
|
/// validation-only 入口:目录树等只读呈现取全部阻塞原因,不组装运行时文档。
|
|
static func invalidReasons(
|
|
_ fields: ServerFields,
|
|
plugins: PluginExecutableResolving
|
|
) -> [LeafInvalidationReason] {
|
|
prepare(fields, plugins: plugins).issues
|
|
}
|
|
|
|
private static func appendAddressIssue(
|
|
_ address: String, to issues: inout [LeafInvalidationReason]
|
|
) {
|
|
if address.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
issues.append(.invalidAddress)
|
|
}
|
|
}
|
|
|
|
private static func appendPortIssue(
|
|
_ port: Int, to issues: inout [LeafInvalidationReason]
|
|
) {
|
|
if !(1...65_535).contains(port) { issues.append(.invalidPort(port)) }
|
|
}
|
|
|
|
private static func appendMethodIssue(
|
|
_ method: String, to issues: inout [LeafInvalidationReason]
|
|
) {
|
|
let trimmed = method.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
if trimmed.isEmpty {
|
|
issues.append(.missingEncryptionMethod)
|
|
} else if !EncryptionMethodCatalog.isSupported(trimmed) {
|
|
issues.append(.unsupportedEncryptionMethod(trimmed))
|
|
}
|
|
}
|
|
}
|