Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 ""
}
Expand All @@ -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)"
}
Expand Down
3 changes: 3 additions & 0 deletions Code/Uplynk/Source/UplynkSSAIConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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(),
Expand All @@ -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
Expand Down