mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-04 01:21:43 +00:00
* feat: add native inline widget support * refactor: simplify plugin surface refresh * fix: preserve plugin surface refresh API * fix: reload widgets after WebKit termination * fix: harden native widget refresh * fix: bound native widget recovery * docs: defer native widget release note * chore: refresh native i18n inventory * fix: harden native widget delivery * refactor: simplify native widget API surface * fix: serialize native widget capability refresh * fix: harden native widget recovery * fix: recover native widget capabilities * style: format widget refresh role selection * fix: correct widget refresh formatting * fix: harden cross-platform widget recovery * fix: bind widget trust and recovery to routes * chore: refresh native i18n inventory * chore: regenerate Android gateway protocol * test: remove unused release workflow read
58 lines
2.5 KiB
Swift
58 lines
2.5 KiB
Swift
import Foundation
|
|
|
|
public enum GatewayPluginSurfaceURL {
|
|
public static func canonicalize(raw: String?, against activeGatewayURL: URL?) -> String? {
|
|
let trimmed = raw?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
|
guard !trimmed.isEmpty else { return nil }
|
|
guard var parsed = URLComponents(string: trimmed) else { return trimmed }
|
|
|
|
let parsedHost = parsed.host?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
|
let parsedIsLoopback = !parsedHost.isEmpty && LoopbackHost.isLoopback(parsedHost)
|
|
|
|
if !parsedHost.isEmpty, !parsedIsLoopback {
|
|
guard let activeGatewayURL else { return trimmed }
|
|
let isTLS = activeGatewayURL.scheme?.lowercased() == "wss"
|
|
guard isTLS else { return trimmed }
|
|
parsed.scheme = "https"
|
|
if parsed.port == nil {
|
|
let tlsPort = activeGatewayURL.port ?? 443
|
|
parsed.port = (tlsPort == 443) ? nil : tlsPort
|
|
}
|
|
return parsed.string ?? trimmed
|
|
}
|
|
|
|
guard let activeGatewayURL,
|
|
let fallbackHost = activeGatewayURL.host,
|
|
!LoopbackHost.isLoopback(fallbackHost)
|
|
else { return trimmed }
|
|
let isTLS = activeGatewayURL.scheme?.lowercased() == "wss"
|
|
parsed.scheme = isTLS ? "https" : "http"
|
|
parsed.host = fallbackHost
|
|
let fallbackPort = activeGatewayURL.port ?? (isTLS ? 443 : 80)
|
|
parsed.port = ((isTLS && fallbackPort == 443) || (!isTLS && fallbackPort == 80)) ? nil : fallbackPort
|
|
return parsed.string ?? trimmed
|
|
}
|
|
|
|
static func tlsFingerprintForSurface(
|
|
_ fingerprint: String?,
|
|
surfaceURL: String,
|
|
gatewayURL: URL?) -> String?
|
|
{
|
|
guard let fingerprint,
|
|
let gatewayURL,
|
|
gatewayURL.scheme?.lowercased() == "wss",
|
|
let surface = URLComponents(string: surfaceURL),
|
|
surface.scheme?.lowercased() == "https",
|
|
self.normalizedEndpointHost(surface.host) == self.normalizedEndpointHost(gatewayURL.host),
|
|
(surface.port ?? 443) == (gatewayURL.port ?? 443)
|
|
else { return nil }
|
|
return fingerprint
|
|
}
|
|
|
|
private static func normalizedEndpointHost(_ raw: String?) -> String? {
|
|
let host = raw?.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() ?? ""
|
|
let normalized = host.hasSuffix(".") ? String(host.dropLast()) : host
|
|
return normalized.isEmpty ? nil : normalized
|
|
}
|
|
}
|