Skip to content

Commit

Permalink
Fix #3265 - pbs cookie sync race condition (#3393)
Browse files Browse the repository at this point in the history
* Fix #3265 - pbs cookie sync race condition

* add/update jsdoc comments
  • Loading branch information
jsnellbaker authored and mkendall07 committed Jan 3, 2019
1 parent 3c9592f commit 74dcdfa
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
24 changes: 20 additions & 4 deletions modules/prebidServerBidAdapter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ function queueSync(bidderCodes, gdprConsent) {
(response) => {
try {
response = JSON.parse(response);
response.bidder_status.forEach(bidder => doBidderSync(bidder.usersync.type, bidder.usersync.url, bidder.bidder));
doAllSyncs(response.bidder_status);
} catch (e) {
utils.logError(e);
}
Expand All @@ -162,24 +162,40 @@ function queueSync(bidderCodes, gdprConsent) {
});
}

function doAllSyncs(bidders) {
if (bidders.length === 0) {
return;
}

const thisSync = bidders.pop();
if (thisSync.no_cookie) {
doBidderSync(thisSync.usersync.type, thisSync.usersync.url, thisSync.bidder, doAllSyncs.bind(null, bidders));
} else {
doAllSyncs(bidders);
}
}

/**
* Run a cookie sync for the given type, url, and bidder
*
* @param {string} type the type of sync, "image", "redirect", "iframe"
* @param {string} url the url to sync
* @param {string} bidder name of bidder doing sync for
* @param {function} done an exit callback; to signify this pixel has either: finished rendering or something went wrong
*/
function doBidderSync(type, url, bidder) {
function doBidderSync(type, url, bidder, done) {
if (!url) {
utils.logError(`No sync url for bidder "${bidder}": ${url}`);
done();
} else if (type === 'image' || type === 'redirect') {
utils.logMessage(`Invoking image pixel user sync for bidder: "${bidder}"`);
utils.triggerPixel(url);
utils.triggerPixel(url, done);
} else if (type == 'iframe') {
utils.logMessage(`Invoking iframe user sync for bidder: "${bidder}"`);
utils.insertUserSyncIframe(url);
utils.insertUserSyncIframe(url, done);
} else {
utils.logError(`User sync type "${type}" not supported for bidder: "${bidder}"`);
done();
}
}

Expand Down
18 changes: 16 additions & 2 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -568,8 +568,17 @@ exports.insertElement = function(elm, doc, target) {
} catch (e) {}
};

exports.triggerPixel = function (url) {
/**
* Inserts an image pixel with the specified `url` for cookie sync
* @param {string} url URL string of the image pixel to load
* @param {function} [done] an optional exit callback, used when this usersync pixel is added during an async process
*/
exports.triggerPixel = function (url, done) {
const img = new Image();
if (done && exports.isFn(done)) {
img.addEventListener('load', done);
img.addEventListener('error', done);
}
img.src = url;
};

Expand Down Expand Up @@ -615,12 +624,17 @@ exports.insertHtmlIntoIframe = function(htmlCode) {
* Inserts empty iframe with the specified `url` for cookie sync
* @param {string} url URL to be requested
* @param {string} encodeUri boolean if URL should be encoded before inserted. Defaults to true
* @param {function} [done] an optional exit callback, used when this usersync pixel is added during an async process
*/
exports.insertUserSyncIframe = function(url) {
exports.insertUserSyncIframe = function(url, done) {
let iframeHtml = exports.createTrackPixelIframeHtml(url, false, 'allow-scripts allow-same-origin');
let div = document.createElement('div');
div.innerHTML = iframeHtml;
let iframe = div.firstChild;
if (done && exports.isFn(done)) {
iframe.addEventListener('load', done);
iframe.addEventListener('error', done);
}
exports.insertElement(iframe);
};

Expand Down

0 comments on commit 74dcdfa

Please sign in to comment.