From 29da12eabf23b23abafd03b7f914cc5e43d09c33 Mon Sep 17 00:00:00 2001 From: aszydlo Date: Wed, 10 Sep 2025 11:10:39 +0200 Subject: [PATCH 1/4] switch to POST when csr URL is too long --- modules/dasBidAdapter.js | 20 +++++- package-lock.json | 27 -------- test/spec/modules/dasBidAdapter_spec.js | 88 +++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 28 deletions(-) diff --git a/modules/dasBidAdapter.js b/modules/dasBidAdapter.js index 76e70f38f9a..d189902c64c 100644 --- a/modules/dasBidAdapter.js +++ b/modules/dasBidAdapter.js @@ -271,10 +271,28 @@ export const spec = { buildRequests: function (validBidRequests, bidderRequest) { const data = buildOpenRTBRequest(validBidRequests, bidderRequest); const jsonData = encodeURIComponent(JSON.stringify(data)); + const baseUrl = getEndpoint(data.ext.network); + const fullUrl = `${baseUrl}?data=${jsonData}`; + + // Switch to POST if URL exceeds 8k characters + if (fullUrl.length > 8192) { + return { + method: 'POST', + url: baseUrl, + data: `data=${jsonData}`, + options: { + withCredentials: true, + crossOrigin: true, + customHeaders: { + 'Content-Type': 'text/plain' + } + }, + }; + } return { method: 'GET', - url: `${getEndpoint(data.ext.network)}?data=${jsonData}`, + url: fullUrl, options: { withCredentials: true, crossOrigin: true, diff --git a/package-lock.json b/package-lock.json index c0cbb0bdd1e..b6f40acde21 100644 --- a/package-lock.json +++ b/package-lock.json @@ -514,21 +514,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/parser": { "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", @@ -29212,18 +29197,6 @@ "@babel/types": "^7.26.10" } }, - "@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - } - }, "@babel/parser": { "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", diff --git a/test/spec/modules/dasBidAdapter_spec.js b/test/spec/modules/dasBidAdapter_spec.js index 714360cc205..de7c9f69fb0 100644 --- a/test/spec/modules/dasBidAdapter_spec.js +++ b/test/spec/modules/dasBidAdapter_spec.js @@ -178,6 +178,94 @@ describe('dasBidAdapter', function () { expect(payload.imp[0].tagid).to.equal('slot1'); expect(payload.imp[0].banner.format[0]).to.deep.equal({ w: 300, h: 250 }); }); + + it('should use GET method when URL is under 8192 characters', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.method).to.equal('GET'); + expect(request.url).to.include('?data='); + expect(request.data).to.be.undefined; + }); + + it('should switch to POST method when URL exceeds 8192 characters', function () { + // Create a large bid request that will result in URL > 8k characters + const largeBidRequests = []; + for (let i = 0; i < 50; i++) { + largeBidRequests.push({ + bidId: `bid${i}`.repeat(20), // Make bid IDs longer + params: { + site: `site${i}`.repeat(50), + area: `area${i}`.repeat(50), + slot: `slot${i}`.repeat(50), + network: 'network1', + pageContext: { + du: `https://very-long-url-example-${i}.com`.repeat(10), + dr: `https://very-long-referrer-url-${i}.com`.repeat(10), + dv: `version-${i}`.repeat(20), + keyWords: Array(20).fill(`keyword${i}`), + capping: `cap${i}`.repeat(20), + keyValues: { + [`key${i}`]: `value${i}`.repeat(50) + } + }, + customParams: { + [`param${i}`]: `value${i}`.repeat(50) + } + }, + mediaTypes: { + banner: { + sizes: [[300, 250], [728, 90], [970, 250]] + } + } + }); + } + + const request = spec.buildRequests(largeBidRequests, bidderRequest); + + expect(request.method).to.equal('POST'); + expect(request.url).to.equal('https://csr.onet.pl/network1/bid'); + expect(request.data).to.be.a('string'); + expect(request.data).to.include('data='); + expect(request.options.customHeaders['Content-Type']).to.equal('text/plain'); + }); + + it('should create valid POST data format', function () { + // Create a request that will trigger POST + const largeBidRequests = Array(50).fill(0).map((_, i) => ({ + bidId: `bid${i}`.repeat(20), + params: { + site: `site${i}`.repeat(50), + area: `area${i}`.repeat(50), + slot: `slot${i}`.repeat(50), + network: 'network1', + pageContext: { + du: `https://very-long-url-example-${i}.com`.repeat(10), + dr: `https://very-long-referrer-url-${i}.com`.repeat(10), + keyWords: Array(10).fill(`keyword${i}`) + } + }, + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + } + })); + + const request = spec.buildRequests(largeBidRequests, bidderRequest); + + expect(request.method).to.equal('POST'); + + // Parse the POST data + const postData = request.data; + expect(postData).to.include('data='); + + const urlParams = new URLSearchParams(postData); + expect(urlParams.has('data')).to.be.true; + + const payload = JSON.parse(decodeURIComponent(urlParams.get('data'))); + expect(payload.id).to.equal('reqId123'); + expect(payload.imp).to.be.an('array').with.length(50); + expect(payload.ext.network).to.equal('network1'); + }); }); describe('interpretResponse', function () { From 01d216c8936a2d6bd5b6f0c7d18bee3a71584e71 Mon Sep 17 00:00:00 2001 From: aszydlo Date: Wed, 10 Sep 2025 12:32:27 +0200 Subject: [PATCH 2/4] fix POST --- modules/dasBidAdapter.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/dasBidAdapter.js b/modules/dasBidAdapter.js index d189902c64c..5203e126a1f 100644 --- a/modules/dasBidAdapter.js +++ b/modules/dasBidAdapter.js @@ -105,7 +105,7 @@ function buildUserIds(customParams) { function getNpaFromPubConsent(pubConsent) { const params = new URLSearchParams(pubConsent); - return params.get('npa') == '1'; + return params.get('npa') === '1'; } function buildOpenRTBRequest(bidRequests, bidderRequest) { @@ -113,7 +113,7 @@ function buildOpenRTBRequest(bidRequests, bidderRequest) { bidRequests[0].params, bidderRequest, ); - const imp = bidRequests.map((bid, index) => { + const imp = bidRequests.map((bid) => { const sizes = getAdUnitSizes(bid); const imp = { id: bid.bidId, @@ -270,16 +270,16 @@ export const spec = { buildRequests: function (validBidRequests, bidderRequest) { const data = buildOpenRTBRequest(validBidRequests, bidderRequest); - const jsonData = encodeURIComponent(JSON.stringify(data)); + const jsonData = JSON.stringify(data); const baseUrl = getEndpoint(data.ext.network); - const fullUrl = `${baseUrl}?data=${jsonData}`; + const fullUrl = `${baseUrl}?data=${encodeURIComponent(jsonData)}`; // Switch to POST if URL exceeds 8k characters if (fullUrl.length > 8192) { return { method: 'POST', url: baseUrl, - data: `data=${jsonData}`, + data: jsonData, options: { withCredentials: true, crossOrigin: true, From caacba9a0890e8da9b4f46e05554205b07d7dc1d Mon Sep 17 00:00:00 2001 From: aszydlo Date: Wed, 10 Sep 2025 12:38:39 +0200 Subject: [PATCH 3/4] package lock --- package-lock.json | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/package-lock.json b/package-lock.json index b6f40acde21..c0cbb0bdd1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -514,6 +514,21 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/parser": { "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", @@ -29197,6 +29212,18 @@ "@babel/types": "^7.26.10" } }, + "@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, "@babel/parser": { "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", From de42b63ad2f53da5c376f6e71967653f9efbdf3b Mon Sep 17 00:00:00 2001 From: aszydlo Date: Wed, 10 Sep 2025 13:06:50 +0200 Subject: [PATCH 4/4] fix test --- test/spec/modules/dasBidAdapter_spec.js | 386 ++++++++++++------------ 1 file changed, 192 insertions(+), 194 deletions(-) diff --git a/test/spec/modules/dasBidAdapter_spec.js b/test/spec/modules/dasBidAdapter_spec.js index de7c9f69fb0..07b86210c74 100644 --- a/test/spec/modules/dasBidAdapter_spec.js +++ b/test/spec/modules/dasBidAdapter_spec.js @@ -224,7 +224,11 @@ describe('dasBidAdapter', function () { expect(request.method).to.equal('POST'); expect(request.url).to.equal('https://csr.onet.pl/network1/bid'); expect(request.data).to.be.a('string'); - expect(request.data).to.include('data='); + + // Check if data is valid JSON (not URL-encoded form data) + const payload = JSON.parse(request.data); + expect(payload.id).to.equal('reqId123'); + expect(payload.imp).to.be.an('array'); expect(request.options.customHeaders['Content-Type']).to.equal('text/plain'); }); @@ -254,101 +258,151 @@ describe('dasBidAdapter', function () { expect(request.method).to.equal('POST'); - // Parse the POST data - const postData = request.data; - expect(postData).to.include('data='); - - const urlParams = new URLSearchParams(postData); - expect(urlParams.has('data')).to.be.true; - - const payload = JSON.parse(decodeURIComponent(urlParams.get('data'))); + // Parse the POST data as JSON (not URL-encoded) + const payload = JSON.parse(request.data); expect(payload.id).to.equal('reqId123'); expect(payload.imp).to.be.an('array').with.length(50); expect(payload.ext.network).to.equal('network1'); }); - }); - describe('interpretResponse', function () { - const serverResponse = { - body: { - seatbid: [{ - bid: [{ - impid: 'bid123', - price: 3.5, - w: 300, - h: 250, - adm: '', - crid: 'crid123', - mtype: 1, - adomain: ['advertiser.com'] - }] - }], - cur: 'USD' - } - }; + describe('interpretResponse', function () { + const serverResponse = { + body: { + seatbid: [{ + bid: [{ + impid: 'bid123', + price: 3.5, + w: 300, + h: 250, + adm: '', + crid: 'crid123', + mtype: 1, + adomain: ['advertiser.com'] + }] + }], + cur: 'USD' + } + }; - it('should return proper bid response', function () { - const bidResponses = spec.interpretResponse(serverResponse); - - expect(bidResponses).to.be.an('array').with.lengthOf(1); - expect(bidResponses[0]).to.deep.include({ - requestId: 'bid123', - cpm: 3.5, - currency: 'USD', - width: 300, - height: 250, - ad: '', - creativeId: 'crid123', - netRevenue: true, - ttl: 300, - mediaType: 'banner' + it('should return proper bid response', function () { + const bidResponses = spec.interpretResponse(serverResponse); + + expect(bidResponses).to.be.an('array').with.lengthOf(1); + expect(bidResponses[0]).to.deep.include({ + requestId: 'bid123', + cpm: 3.5, + currency: 'USD', + width: 300, + height: 250, + ad: '', + creativeId: 'crid123', + netRevenue: true, + ttl: 300, + mediaType: 'banner' + }); + expect(bidResponses[0].meta.advertiserDomains).to.deep.equal(['advertiser.com']); }); - expect(bidResponses[0].meta.advertiserDomains).to.deep.equal(['advertiser.com']); - }); - it('should return empty array when no valid responses', function () { - expect(spec.interpretResponse({ body: null })).to.be.an('array').that.is.empty; - expect(spec.interpretResponse({ body: {} })).to.be.an('array').that.is.empty; - expect(spec.interpretResponse({ body: { seatbid: [] } })).to.be.an('array').that.is.empty; + it('should return empty array when no valid responses', function () { + expect(spec.interpretResponse({ body: null })).to.be.an('array').that.is.empty; + expect(spec.interpretResponse({ body: {} })).to.be.an('array').that.is.empty; + expect(spec.interpretResponse({ body: { seatbid: [] } })).to.be.an('array').that.is.empty; + }); + + it('should return proper bid response for native', function () { + const nativeResponse = { + body: { + seatbid: [{ + bid: [{ + impid: 'bid123', + price: 3.5, + w: 1, + h: 1, + adm: JSON.stringify({ + fields: { + Body: 'Ruszyła sprzedaż mieszkań przy Metrze Dworzec Wileński', + Calltoaction: 'SPRAWDŹ', + Headline: 'Gotowe mieszkania w świetnej lokalizacji (test)', + Image: 'https://ocdn.eu/example.jpg', + Sponsorlabel: 'tak', + Thirdpartyclicktracker: '', + Thirdpartyimpressiontracker: '', + Thirdpartyimpressiontracker2: '', + borderColor: '#CECECE', + click: 'https://mieszkaniaprzymetrodworzec.pl', + responsive: 'nie' + }, + tplCode: '1746213/Native-In-Feed', + meta: { + inIFrame: false, + autoscale: 0, + width: '1', + height: '1', + adid: 'das,1778361,669261', + actioncount: 'https://csr.onet.pl/eclk/...', + slot: 'right2', + adclick: 'https://csr.onet.pl/clk/...', + container_wrapper: '
REKLAMA
', + prebid_native: true + } + }), + mtype: 4 + }] + }], + cur: 'USD' + } + }; + + const bidResponses = spec.interpretResponse(nativeResponse); + + expect(bidResponses).to.be.an('array').with.lengthOf(1); + expect(bidResponses[0]).to.deep.include({ + requestId: 'bid123', + cpm: 3.5, + currency: 'USD', + width: 1, + height: 1, + native: { + title: 'Gotowe mieszkania w świetnej lokalizacji (test)', + body: 'Ruszyła sprzedaż mieszkań przy Metrze Dworzec Wileński', + cta: 'SPRAWDŹ', + image: { + url: 'https://ocdn.eu/example.jpg', + width: '1', + height: '1' + }, + icon: { + url: '', + width: '1', + height: '1' + }, + clickUrl: 'https://csr.onet.pl/clk/...https://mieszkaniaprzymetrodworzec.pl', + body2: '', + sponsoredBy: '', + clickTrackers: [], + impressionTrackers: [], + javascriptTrackers: [], + sendTargetingKeys: false + }, + netRevenue: true, + ttl: 300, + mediaType: 'native' + }); + + expect(bidResponses[0]).to.not.have.property('ad'); + }); }); - it('should return proper bid response for native', function () { + it('should return empty object when adm in a native response is not JSON', function () { const nativeResponse = { body: { seatbid: [{ bid: [{ - impid: 'bid123', - price: 3.5, + impid: 'bad1', + price: 2.0, w: 1, h: 1, - adm: JSON.stringify({ - fields: { - Body: 'Ruszyła sprzedaż mieszkań przy Metrze Dworzec Wileński', - Calltoaction: 'SPRAWDŹ', - Headline: 'Gotowe mieszkania w świetnej lokalizacji (test)', - Image: 'https://ocdn.eu/example.jpg', - Sponsorlabel: 'tak', - Thirdpartyclicktracker: '', - Thirdpartyimpressiontracker: '', - Thirdpartyimpressiontracker2: '', - borderColor: '#CECECE', - click: 'https://mieszkaniaprzymetrodworzec.pl', - responsive: 'nie' - }, - tplCode: '1746213/Native-In-Feed', - meta: { - inIFrame: false, - autoscale: 0, - width: '1', - height: '1', - adid: 'das,1778361,669261', - actioncount: 'https://csr.onet.pl/eclk/...', - slot: 'right2', - adclick: 'https://csr.onet.pl/clk/...', - container_wrapper: '
REKLAMA
', - prebid_native: true - } - }), + adm: 'not-a-json-string', mtype: 4 }] }], @@ -357,126 +411,70 @@ describe('dasBidAdapter', function () { }; const bidResponses = spec.interpretResponse(nativeResponse); - - expect(bidResponses).to.be.an('array').with.lengthOf(1); - expect(bidResponses[0]).to.deep.include({ - requestId: 'bid123', - cpm: 3.5, - currency: 'USD', - width: 1, - height: 1, - native: { - title: 'Gotowe mieszkania w świetnej lokalizacji (test)', - body: 'Ruszyła sprzedaż mieszkań przy Metrze Dworzec Wileński', - cta: 'SPRAWDŹ', - image: { - url: 'https://ocdn.eu/example.jpg', - width: '1', - height: '1' - }, - icon: { - url: '', - width: '1', - height: '1' - }, - clickUrl: 'https://csr.onet.pl/clk/...https://mieszkaniaprzymetrodworzec.pl', - body2: '', - sponsoredBy: '', - clickTrackers: [], - impressionTrackers: [], - javascriptTrackers: [], - sendTargetingKeys: false - }, - netRevenue: true, - ttl: 300, - mediaType: 'native' - }); - - expect(bidResponses[0]).to.not.have.property('ad'); + expect(bidResponses[0].native).to.deep.equal({}); }); - }); - - it('should return empty object when adm in a native response is not JSON', function () { - const nativeResponse = { - body: { - seatbid: [{ - bid: [{ - impid: 'bad1', - price: 2.0, - w: 1, - h: 1, - adm: 'not-a-json-string', - mtype: 4 - }] - }], - cur: 'USD' - } - }; - const bidResponses = spec.interpretResponse(nativeResponse); - expect(bidResponses[0].native).to.deep.equal({}); - }); - - it('should return empty object when adm in a native response is missing required fields/meta', function () { - const nativeResponse = { - body: { - seatbid: [{ - bid: [{ - impid: 'bad2', - price: 2.0, - w: 1, - h: 1, - adm: JSON.stringify({ fields: {} }), - mtype: 4 - }] - }], - cur: 'USD' - } - }; + it('should return empty object when adm in a native response is missing required fields/meta', function () { + const nativeResponse = { + body: { + seatbid: [{ + bid: [{ + impid: 'bad2', + price: 2.0, + w: 1, + h: 1, + adm: JSON.stringify({ fields: {} }), + mtype: 4 + }] + }], + cur: 'USD' + } + }; - const bidResponses = spec.interpretResponse(nativeResponse); - expect(bidResponses[0].native).to.deep.equal({}); - }); + const bidResponses = spec.interpretResponse(nativeResponse); + expect(bidResponses[0].native).to.deep.equal({}); + }); - it('should return empty object when adm in a native response is empty JSON object', function () { - const nativeResponse = { - body: { - seatbid: [{ - bid: [{ - impid: 'bad3', - price: 2.0, - w: 1, - h: 1, - adm: JSON.stringify({}), - mtype: 4 - }] - }], - cur: 'USD' - } - }; + it('should return empty object when adm in a native response is empty JSON object', function () { + const nativeResponse = { + body: { + seatbid: [{ + bid: [{ + impid: 'bad3', + price: 2.0, + w: 1, + h: 1, + adm: JSON.stringify({}), + mtype: 4 + }] + }], + cur: 'USD' + } + }; - const bidResponses = spec.interpretResponse(nativeResponse); - expect(bidResponses[0].native).to.deep.equal({}); - }); + const bidResponses = spec.interpretResponse(nativeResponse); + expect(bidResponses[0].native).to.deep.equal({}); + }); - it('should return empty object when adm in a native response is null or missing', function () { - const nativeResponse = { - body: { - seatbid: [{ - bid: [{ - impid: 'bad4', - price: 2.0, - w: 1, - h: 1, - adm: null, - mtype: 4 - }] - }], - cur: 'USD' - } - }; + it('should return empty object when adm in a native response is null or missing', function () { + const nativeResponse = { + body: { + seatbid: [{ + bid: [{ + impid: 'bad4', + price: 2.0, + w: 1, + h: 1, + adm: null, + mtype: 4 + }] + }], + cur: 'USD' + } + }; - const bidResponses = spec.interpretResponse(nativeResponse); - expect(bidResponses[0].native).to.deep.equal({}); + const bidResponses = spec.interpretResponse(nativeResponse); + expect(bidResponses[0].native).to.deep.equal({}); + }); }); });