|
8 | 8 | // 3. Test your change by following the instructions at https://github.com/HTTPArchive/almanac.httparchive.org/issues/33#issuecomment-502288773. |
9 | 9 | // 4. Submit a PR to update this file. |
10 | 10 |
|
| 11 | +import psl from 'psl'; // Import the psl library for Public Suffix List parsing. |
| 12 | + |
11 | 13 | function fetchWithTimeout(url) { |
12 | 14 | var controller = new AbortController(); |
13 | 15 | setTimeout(() => {controller.abort()}, 5000); |
@@ -79,6 +81,14 @@ function parseResponseWithRedirects(url, parser) { |
79 | 81 | }); |
80 | 82 | } |
81 | 83 |
|
| 84 | +function getRootDomain(hostname) { |
| 85 | + const parsed = psl.parse(hostname); |
| 86 | + if (parsed.error){ |
| 87 | + return hostname; |
| 88 | + } |
| 89 | + return parsed.domain || hostname; // Use parsed.domain, fallback to hostname if null |
| 90 | +} |
| 91 | + |
82 | 92 | return Promise.all([ |
83 | 93 | // ecommerce |
84 | 94 | parseResponse('/.well-known/assetlinks.json', r => { |
@@ -118,22 +128,43 @@ return Promise.all([ |
118 | 128 | }), |
119 | 129 | // Privacy Sandbox |
120 | 130 | parseResponse('/.well-known/related-website-set.json', r => { |
121 | | - return r.text().then(text => { |
122 | | - let result = { |
123 | | - primary: null, |
124 | | - associatedSites: null |
125 | | - }; |
126 | | - |
127 | | - try { |
128 | | - let data = JSON.parse(text); |
129 | | - result.primary = data.primary || null; |
130 | | - result.associatedSites = data.associatedSites || null; |
131 | | - } catch (e) { |
132 | | - // Failed to parse JSON, result will contain default values. |
133 | | - } |
134 | | - |
135 | | - return result; |
136 | | - }); |
| 131 | + return fetchWithTimeout(r.url) |
| 132 | + .then(response => { |
| 133 | + if (!response.ok) { |
| 134 | + // Retry logic |
| 135 | + const domain = getRootDomain(window.location.hostname); |
| 136 | + const retryUrl = `https://${domain}/.well-known/related-website-set.json`; |
| 137 | + return fetchWithTimeout(retryUrl) |
| 138 | + .then(retryResponse => { |
| 139 | + if (!retryResponse.ok) { |
| 140 | + throw new Error(`Retry failed with status: ${retryResponse.status}`); |
| 141 | + } |
| 142 | + return retryResponse.text(); |
| 143 | + }); |
| 144 | + } |
| 145 | + return response.text(); |
| 146 | + }) |
| 147 | + .then(text => { |
| 148 | + let result = { |
| 149 | + primary: null, |
| 150 | + associatedSites: null |
| 151 | + }; |
| 152 | + try { |
| 153 | + const data = JSON.parse(text); |
| 154 | + result.primary = data.primary || null; |
| 155 | + result.associatedSites = data.associatedSites || null; |
| 156 | + } catch (e) { |
| 157 | + // Failed to parse JSON, result will contain default values (already set). |
| 158 | + } |
| 159 | + return result; |
| 160 | + }) |
| 161 | + .catch(error => { |
| 162 | + // Return null object on any error |
| 163 | + return { |
| 164 | + primary: null, |
| 165 | + associatedSites: null |
| 166 | + }; |
| 167 | + }); |
137 | 168 | }), |
138 | 169 | parseResponse('/.well-known/privacy-sandbox-attestations.json'), //Attestation File |
139 | 170 | // privacy |
|
0 commit comments