Skip to content

Commit

Permalink
fix: Fix duplicate CMCD parameters in HLS live content (#3875)
Browse files Browse the repository at this point in the history
Use goog.Uri to append CMCD query data to avoid duplicate query params

Fixes #3862

Co-authored-by: Dan Sparacio <daniel.sparacio@cbsinteractive.com>
  • Loading branch information
littlespex and dsparacio committed Jan 25, 2022
1 parent e9df8fb commit f27401c
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 11 deletions.
8 changes: 5 additions & 3 deletions lib/util/cmcd_manager.js
Expand Up @@ -6,6 +6,7 @@

goog.provide('shaka.util.CmcdManager');

goog.require('goog.Uri');
goog.require('shaka.log');


Expand Down Expand Up @@ -534,7 +535,7 @@ shaka.util.CmcdManager = class {
* @return {string}
*/
static toQuery(data) {
return `CMCD=${encodeURIComponent(shaka.util.CmcdManager.serialize(data))}`;
return shaka.util.CmcdManager.serialize(data);
}

/**
Expand All @@ -553,8 +554,9 @@ shaka.util.CmcdManager = class {
return uri;
}

const separator = uri.includes('?') ? '&' : '?';
return `${uri}${separator}${query}`;
const url = new goog.Uri(uri);
url.getQueryData().set('CMCD', query);
return url.toString();
}
};

Expand Down
14 changes: 6 additions & 8 deletions test/util/cmcd_manager_unit.js
Expand Up @@ -33,21 +33,19 @@ describe('CmcdManager', () => {
describe('Query serialization', () => {
it('produces correctly serialized data', () => {
const query = CmcdManager.toQuery(data);
const result = 'CMCD=br%3D52317%2Cbs%2Ccid%3D%22xyz%22%2C' +
'com.test-exists%2Ccom.test-hello%3D%22world%22%2C' +
'com.test-testing%3D1234%2Ccom.test-token%3Ds%2C' +
'd%3D6067%2Cmtp%3D10000%2C' +
'nor%3D%22..%252Ftesting%252F3.m4v%22%2C' +
'nrr%3D%220-99%22%2C' +
'sid%3D%22c936730c-031e-4a73-976f-92bc34039c60%22';
const result = 'br=52317,bs,cid="xyz",com.test-exists,' +
'com.test-hello="world",com.test-testing=1234,' +
'com.test-token=s,d=6067,mtp=10000,' +
'nor="..%2Ftesting%2F3.m4v",nrr="0-99",' +
'sid="c936730c-031e-4a73-976f-92bc34039c60"';
expect(query).toBe(result);
});

it('escapes reserve character in string values', () => {
const query = CmcdManager.toQuery({
'com.test-escape': 'Double "Quotes"',
});
const result = 'CMCD=com.test-escape%3D%22Double%20%5C%22Quotes%5C%22%22';
const result = 'com.test-escape="Double \\"Quotes\\""';
expect(query).toBe(result);
});
});
Expand Down
21 changes: 21 additions & 0 deletions third_party/closure-uri/uri.js
Expand Up @@ -808,6 +808,27 @@ goog.Uri.QueryData.prototype.add = function(key, value) {
return this;
};

/**
* Sets a key value pair and removes all other keys with the same value.
*
* @param {string} key Name.
* @param {string} value Value.
* @return {!goog.Uri.QueryData} Instance of this object.
*/
goog.Uri.QueryData.prototype.set = function(key, value) {
this.ensureKeyMapInitialized_();
// Invalidate the cache.
this.encodedQuery_ = null;

if (!this.keyMap_.hasOwnProperty(key)) {
this.add(key, value);
} else {
this.keyMap_[key] = [value];
}

return this;
};


/**
* @return {string} Encoded query string.
Expand Down

0 comments on commit f27401c

Please sign in to comment.