From 78eaa34a635975cf8d7257b03a8a9a52318cb572 Mon Sep 17 00:00:00 2001 From: Ruben Garcia Date: Wed, 4 Feb 2026 20:25:15 -0500 Subject: [PATCH 1/2] Add ordered params support and fix url encoding for Uplynk signature validation --- .../UplynkSSAIConfiguration+Extensions.swift | 15 ++++++++++++++- Code/Uplynk/Source/UplynkSSAIConfiguration.swift | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Code/Uplynk/Source/Internal/UplynkSSAIConfiguration+Extensions.swift b/Code/Uplynk/Source/Internal/UplynkSSAIConfiguration+Extensions.swift index fab531df..a962b2a8 100644 --- a/Code/Uplynk/Source/Internal/UplynkSSAIConfiguration+Extensions.swift +++ b/Code/Uplynk/Source/Internal/UplynkSSAIConfiguration+Extensions.swift @@ -14,6 +14,19 @@ extension UplynkSSAIConfiguration { } var urlParameters: String { + if let orderedParams = orderedPreplayParameters, !orderedParams.isEmpty { + // Define strict allowed characters for query values + // We MUST encode '%' (to preserve pre-encoded values), '&', '=', '+', and others that alter URL structure. + var allowed = CharacterSet.urlQueryAllowed + allowed.remove(charactersIn: "&+=?%,") + + let joinedParameters = orderedParams.map { (key, value) in + let encodedValue = value.addingPercentEncoding(withAllowedCharacters: allowed) ?? value + return "\(key)=\(encodedValue)" + }.joined(separator: "&") + return "&\(joinedParameters)" + } + guard !preplayParameters.isEmpty else { return "" } @@ -31,7 +44,7 @@ extension UplynkSSAIConfiguration { var pingParameters: String { let pingFeature = pingFeature if pingFeature == .noPing { - return "&ad.pingc=0" + return "" } else { return "&ad.pingc=1&ad.pingf=\(pingFeature.rawValue)" } diff --git a/Code/Uplynk/Source/UplynkSSAIConfiguration.swift b/Code/Uplynk/Source/UplynkSSAIConfiguration.swift index 62cd2dd6..7a21c797 100644 --- a/Code/Uplynk/Source/UplynkSSAIConfiguration.swift +++ b/Code/Uplynk/Source/UplynkSSAIConfiguration.swift @@ -27,6 +27,7 @@ public class UplynkSSAIConfiguration: CustomServerSideAdInsertionConfiguration { public let id: ID public let prefix: String? public let preplayParameters: [String: String] + public let orderedPreplayParameters: [(String, String)]? public let assetType: AssetType public let contentProtected: Bool public let assetInfo: Bool @@ -38,6 +39,7 @@ public class UplynkSSAIConfiguration: CustomServerSideAdInsertionConfiguration { assetType: AssetType, prefix: String? = nil, preplayParameters: [String: String] = [:], + orderedPreplayParameters: [(String, String)]? = nil, contentProtected: Bool = false, assetInfo: Bool = false, uplynkPingConfiguration: UplynkPingConfiguration = .init(), @@ -47,6 +49,7 @@ public class UplynkSSAIConfiguration: CustomServerSideAdInsertionConfiguration { self.assetType = assetType self.prefix = prefix self.preplayParameters = preplayParameters + self.orderedPreplayParameters = orderedPreplayParameters self.contentProtected = contentProtected self.assetInfo = assetInfo self.pingConfiguration = uplynkPingConfiguration From 315ee522fa49130fc208a08e64786c862b55d828 Mon Sep 17 00:00:00 2001 From: Ruben Garcia Date: Thu, 5 Feb 2026 07:13:53 -0500 Subject: [PATCH 2/2] docs: add changelog entry for ordered params and encoding fix --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26ea0749..91e5d574 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Added `orderedPreplayParameters` to `UplynkSSAIConfiguration` and fixed URL encoding for valid Uplynk signatures. + ## [10.8.0.1] - 2026-01-20 ### Fixed