diff --git a/modules/rubiconAnalyticsAdapter.js b/modules/rubiconAnalyticsAdapter.js index 939afc42f6d..9bb8a924b98 100644 --- a/modules/rubiconAnalyticsAdapter.js +++ b/modules/rubiconAnalyticsAdapter.js @@ -37,11 +37,14 @@ const cache = { timeouts: {}, }; -let referrerHostname; - -function getHostNameFromReferer(referer) { - referrerHostname = urlLib.parse(referer).hostname; - return referrerHostname; +export function getHostNameFromReferer(referer) { + try { + rubiconAdapter.referrerHostname = urlLib.parse(referer, {noDecodeWholeURL: true}).hostname; + } catch (e) { + utils.logError('Rubicon Analytics: Unable to parse hostname from supplied url: ', referer, e); + rubiconAdapter.referrerHostname = ''; + } + return rubiconAdapter.referrerHostname }; function stringProperties(obj) { @@ -124,7 +127,7 @@ function sendMessage(auctionId, bidWonId) { integration: config.getConfig('rubicon.int_type') || DEFAULT_INTEGRATION, version: '$prebid.version$', referrerUri: referrer, - referrerHostname: referrerHostname || getHostNameFromReferer(referrer) + referrerHostname: rubiconAdapter.referrerHostname || getHostNameFromReferer(referrer) }; const wrapperName = config.getConfig('rubicon.wrapperName'); if (wrapperName) { @@ -269,6 +272,7 @@ function setRubiconAliases(aliasRegistry) { let baseAdapter = adapter({analyticsType: 'endpoint'}); let rubiconAdapter = Object.assign({}, baseAdapter, { + referrerHostname: '', enableAnalytics(config = {}) { let error = false; samplingFactor = 1; diff --git a/test/spec/modules/rubiconAnalyticsAdapter_spec.js b/test/spec/modules/rubiconAnalyticsAdapter_spec.js index 2ad828ef3e0..1e71a43999d 100644 --- a/test/spec/modules/rubiconAnalyticsAdapter_spec.js +++ b/test/spec/modules/rubiconAnalyticsAdapter_spec.js @@ -1,4 +1,8 @@ -import rubiconAnalyticsAdapter, { SEND_TIMEOUT, parseBidResponse } from 'modules/rubiconAnalyticsAdapter.js'; +import rubiconAnalyticsAdapter, { + SEND_TIMEOUT, + parseBidResponse, + getHostNameFromReferer, +} from 'modules/rubiconAnalyticsAdapter.js'; import CONSTANTS from 'src/constants.json'; import { config } from 'src/config.js'; import { server } from 'test/mocks/xhr.js'; @@ -22,9 +26,8 @@ function validate(message) { } // using es6 "import * as events from 'src/events.js'" causes the events.getEvents stub not to work... -let events = require('src/events'); -let ajax = require('src/ajax'); -let utils = require('src/utils'); +let events = require('src/events.js'); +let utils = require('src/utils.js'); const { EVENTS: { @@ -477,7 +480,6 @@ function performStandardAuction() { describe('rubicon analytics adapter', function () { let sandbox; - let oldScreen; let clock; beforeEach(function () { @@ -487,6 +489,8 @@ describe('rubicon analytics adapter', function () { clock = sandbox.useFakeTimers(1519767013781); + rubiconAnalyticsAdapter.referrerHostname = ''; + config.setConfig({ s2sConfig: { timeout: 1000, @@ -841,4 +845,19 @@ describe('rubicon analytics adapter', function () { rubiconAnalyticsAdapter.disableAnalytics(); }); }); + + it('getHostNameFromReferer correctly grabs hostname from an input URL', function () { + let inputUrl = 'https://www.prebid.org/some/path?pbjs_debug=true'; + expect(getHostNameFromReferer(inputUrl)).to.equal('www.prebid.org'); + inputUrl = 'https://www.prebid.com/some/path?pbjs_debug=true'; + expect(getHostNameFromReferer(inputUrl)).to.equal('www.prebid.com'); + inputUrl = 'https://prebid.org/some/path?pbjs_debug=true'; + expect(getHostNameFromReferer(inputUrl)).to.equal('prebid.org'); + inputUrl = 'http://xn--p8j9a0d9c9a.xn--q9jyb4c/'; + expect(getHostNameFromReferer(inputUrl)).to.equal('xn--p8j9a0d9c9a.xn--q9jyb4c'); + + // not non-UTF char's in query / path which break if noDecodeWholeURL not set + inputUrl = 'https://prebid.org/search_results/%95x%8Em%92%CA/?category=000'; + expect(getHostNameFromReferer(inputUrl)).to.equal('prebid.org'); + }); });