AVAssetDownloadURLSession ignores HTTP cache

Trying to download an encrypted HLS stream we faced the following behaviour:

Setting requestCachePolicy and/or urlCache properties of URLSessionConfiguration that used to create the AVAssetDownloadURLSession seems to have no effect at all.

In our application the user can add multiple encrypted HLS streams at a queue. Before adding them in queue, we make sure that the manifest gets cached using the shared URLSession like this:

URLSession.shared.configuration.urlCache = .shared
let task = URLSession.shared.dataTask(with: media.url) { _, _, _ in
    self.addMediaToQueue(media)
}
task.resume()

and we setup our AVAssetDownloadURLSession like this:

// Create the configuration for the AVAssetDownloadURLSession.
let backgroundConfiguration = URLSessionConfiguration.background(withIdentifier: "AAPL-Identifier")
backgroundConfiguration.urlCache = .shared
backgroundConfiguration.requestCachePolicy = .returnCacheDataElseLoad

// Create the AVAssetDownloadURLSession using the configuration.
assetDownloadURLSession = AVAssetDownloadURLSession(
    configuration: backgroundConfiguration,
    assetDownloadDelegate: self,
    delegateQueue: .main
)

Here is an example of the caching headers that we use:

Last-Modified: Thu, 11 Mar 2021 02:23:57 GMT
Cache-Control: max-age=604800

This is important for us since our manifest url is signed and expires after 12 hours.

Example of manifest URL: https://example.host.gr/v1/791/888/773923397316/773923397316.ism/.m3u8[…]~hmac=ee37a750b8238745b5c8cf153ebcd0b693dd5d83

If the client followed the HTTP cache policy and didn’t request the .m3u8 manifest file over the internet, the download would start, despite the 12 hours limit.

Is this the intended behaviour of the download process or some kind of an issue? Could you suggest a workaround?

Have you tried managing your HLS downloads via AVAssetDownloadStorageManagementPolicy instead? Or, since the download completion gives you a URL where the download is stored, you can remove it explicitly in your code using FileManager, if it is no longer valid when you app goes to play it.

Or have I misunderstood the problem you're trying to solve?

HLS doesn't have the concept of downloading playlists, just assets. Playlists are retrieved, of course, and that might be done through a URL session, but that's separate from an asset download (for persistable content). The system may retrieve a playlist at a time of its choosing (rather than, as you're hoping, when the asset download task is initially resume'd), and it may retrieve it more than once.

Also, HLS doesn't have the concept of protecting playlists, just assets. For that, you can use FairPlay Streaming (https://developer.apple.com/streaming/fps), and when you use FPS you can have a timed leasing scheme for your content and its downloads.

I can't really think of a workaround for your scenario. As you described it, your content protection scheme relies on keeping your playlist URL secret for at least the 12 hours that it's valid. If a hacker gained access to the playlist (the file's data, not its URL) during this time, then your content would no longer be protected, right?

If you're OK with relying on the playlist being a secret, then perhaps you don't need the 12-hour expiry window to be enforced by your server. It could be enforced by your client app instead.

AVAssetDownloadURLSession ignores HTTP cache
 
 
Q