-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
581c6a2
commit c1beb76
Showing
6 changed files
with
237 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>AMP loop protection</title> | ||
</head> | ||
<body> | ||
<h1 id="param-display"></h1> | ||
<script> | ||
const MAX = 15; | ||
const LS_ITEM_KEY = 'amp-loop-protection-attempt'; | ||
const newUrl = new URL(location.href); | ||
const isStart = newUrl.searchParams.has('start'); | ||
|
||
if (isStart) { | ||
localStorage[LS_ITEM_KEY] = 0; | ||
} | ||
const attempt = Number.parseInt(localStorage[LS_ITEM_KEY], 10) || 0; | ||
localStorage[LS_ITEM_KEY] = attempt + 1; | ||
|
||
document.getElementById('param-display').innerText = `${newUrl.searchParams}`; | ||
document.body.innerHTML += `<p>Attempt ${attempt + 1}/${MAX}</p>`; | ||
|
||
// set amp attr, count attempts | ||
const params = new URLSearchParams(location.search); | ||
if (params.get('amp') === '1') { | ||
document.documentElement.setAttribute('amp', ''); | ||
const link = document.createElement('link'); | ||
link.setAttribute('rel', 'canonical'); | ||
const ampUrl = new URL('http://good.third-party.site/privacy-protections/amp-loop-protection/amp-only.html'); | ||
if (isStart) { | ||
ampUrl.searchParams.set('start', '1'); | ||
} | ||
link.setAttribute('href', ampUrl.href); | ||
document.head.appendChild(link); | ||
|
||
localStorage.removeItem(LS_ITEM_KEY); | ||
const onMessage = msg => { | ||
if (msg.data.action && msg.data.action === 'url') { | ||
if (window.opener) { | ||
window.opener.postMessage({ url: document.location.href, type: msg.data.type }, '*'); | ||
} else if (window.parent) { | ||
window.parent.postMessage({ url: document.location.href, type: msg.data.type }, '*'); | ||
} | ||
} | ||
}; | ||
|
||
window.addEventListener('message', onMessage); | ||
} else if (attempt < MAX) { | ||
newUrl.searchParams.set('amp', 1); | ||
newUrl.pathname = newUrl.pathname | ||
location.href = newUrl.href; | ||
} | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>AMP loop protection</title> | ||
|
||
<script src='./main.js' defer></script> | ||
<link href='./style.css' rel='stylesheet'></link> | ||
</head> | ||
<body> | ||
<p><a href="../../">[Home]</a> ↣ <a href="../">[Privacy Protections Tests]</a> ↣ <strong>[AMP Upgrade Loop Protection]</strong></p> | ||
|
||
<p>This test will navigate to a non-AMP page that immediately redirects to its AMP version. This will cause a non-AMP↔AMP loop (client trying to get real page, page redirecting). Clients should detect this scenario and allow the AMP page to load.</p> | ||
<p>If the loop protection works the reported url will have the amp=1 parameter.</p> | ||
|
||
<p><button id='start'>Start test</button></p> | ||
|
||
<details id='tests' hidden> | ||
<summary id='tests-summary'></summary> | ||
<ul id='tests-details'> | ||
</ul> | ||
</details> | ||
|
||
<p><button id='download' disabled>Download the result</button></p> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
const startButton = document.querySelector('#start'); | ||
const downloadButton = document.querySelector('#download'); | ||
|
||
const testsDiv = document.querySelector('#tests'); | ||
const testsSummaryDiv = document.querySelector('#tests-summary'); | ||
const testsDetailsDiv = document.querySelector('#tests-details'); | ||
|
||
const TEST_DOMAIN = 'good.third-party.site'; | ||
|
||
const tests = [ | ||
{ | ||
id: 'rewrite-amp', | ||
run: () => { | ||
let res; | ||
const promise = new Promise((resolve, reject) => { res = resolve; }); | ||
const otherWindow = window.open(`http://${TEST_DOMAIN}/privacy-protections/amp-loop-protection/amp-only.html?amp=1&start`); | ||
|
||
const interval = setInterval(() => { | ||
otherWindow.postMessage({ action: 'url', type: 'navigation' }, `http://${TEST_DOMAIN}/`); | ||
}, 500); | ||
|
||
function onMessage (m) { | ||
if (m.data && m.data.type === 'navigation') { | ||
clearInterval(interval); | ||
otherWindow.close(); | ||
window.removeEventListener('message', onMessage); | ||
console.log('navigation', m.data.url); | ||
res(m.data.url); | ||
} | ||
} | ||
|
||
window.addEventListener('message', onMessage); | ||
|
||
return promise; | ||
} | ||
} | ||
]; | ||
|
||
// object that contains results of all tests | ||
const results = { | ||
page: 'amp-loop-protection', | ||
date: null, | ||
results: [] | ||
}; | ||
|
||
function resultToHTML (data) { | ||
if (Array.isArray(data)) { | ||
return `<ul>${data.map(r => `<li>${r.test} - ${r.result}</li>`).join('')}</ul>`; | ||
} else if (data) { | ||
return JSON.stringify(data, null, 2); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/** | ||
* Test runner | ||
*/ | ||
function runTests () { | ||
startButton.setAttribute('disabled', 'disabled'); | ||
downloadButton.removeAttribute('disabled'); | ||
testsDiv.removeAttribute('hidden'); | ||
|
||
results.results.length = 0; | ||
results.date = (new Date()).toUTCString(); | ||
let all = 0; | ||
let failed = 0; | ||
|
||
testsDetailsDiv.innerHTML = ''; | ||
|
||
function updateSummary () { | ||
testsSummaryDiv.innerText = `Performed ${all} tests${failed > 0 ? ` (${failed} failed)` : ''}. Click for details.`; | ||
} | ||
|
||
for (const test of tests) { | ||
const resultObj = { | ||
id: test.id, | ||
value: null | ||
}; | ||
results.results.push(resultObj); | ||
|
||
const li = document.createElement('li'); | ||
li.id = `test-${test.id.replace(' ', '-')}`; | ||
li.innerHTML = `${test.id} - <span class='value'>…</span>`; | ||
const valueSpan = li.querySelector('.value'); | ||
|
||
testsDetailsDiv.appendChild(li); | ||
|
||
try { | ||
const result = test.run(); | ||
|
||
if (result instanceof Promise) { | ||
result | ||
.then(data => { | ||
valueSpan.textContent = resultToHTML(data); | ||
resultObj.value = data || null; | ||
}) | ||
.catch(e => { | ||
failed++; | ||
valueSpan.innerHTML = `❌ error thrown ("${e.message ? e.message : e}")`; | ||
updateSummary(); | ||
}); | ||
} else { | ||
valueSpan.innerHTML = resultToHTML(result); | ||
resultObj.value = result || null; | ||
} | ||
} catch (e) { | ||
failed++; | ||
valueSpan.innerHTML = `❌ error thrown ("${e.message ? e.message : e}")`; | ||
} | ||
|
||
all++; | ||
} | ||
|
||
updateSummary(); | ||
|
||
startButton.removeAttribute('disabled'); | ||
} | ||
|
||
function downloadTheResults () { | ||
const data = JSON.stringify(results, null, 2); | ||
const a = document.createElement('a'); | ||
const url = window.URL.createObjectURL(new Blob([data], { type: 'application/json' })); | ||
a.href = url; | ||
a.download = 'amp-loop-protection-results.json'; | ||
|
||
document.body.appendChild(a); | ||
a.click(); | ||
|
||
window.URL.revokeObjectURL(url); | ||
a.remove(); | ||
} | ||
|
||
downloadButton.addEventListener('click', () => downloadTheResults()); | ||
|
||
// run tests if button was clicked or… | ||
startButton.addEventListener('click', () => runTests()); | ||
|
||
// if url query is '?run' start tests imadiatelly | ||
if (document.location.search === '?run') { | ||
runTests(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
* { | ||
box-sizing: border-box; | ||
} | ||
|
||
.value { | ||
color: gray; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters