forked from scratchfoundation/scratch-vm
-
-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Experiment with
staticFetch
to improve reliability of large data: URLs
- Loading branch information
1 parent
e4e461a
commit 088b0c1
Showing
3 changed files
with
81 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,36 @@ | ||
/** | ||
* @fileoverview | ||
* The new URL() and fetch() provided by the browser tend to buckle when dealing with URLs that are | ||
* tens of megabytes in length, which can be common when working with data: URLs in extensions. | ||
* | ||
* To help avoid that, this file can "statically" parse some data: URLs without going through | ||
* unreliable browser APIs. | ||
*/ | ||
|
||
const Base64Util = require('./base64-util'); | ||
|
||
/** | ||
* @param {string} url | ||
* @returns {Response|null} | ||
*/ | ||
const staticFetch = url => { | ||
try { | ||
const simpleDataUrlMatch = url.match(/^data:([/-\w\d]*);base64,/i); | ||
if (simpleDataUrlMatch) { | ||
const contentType = simpleDataUrlMatch[1].toLowerCase(); | ||
const base64 = url.substring(simpleDataUrlMatch[0].length); | ||
const decoded = Base64Util.base64ToUint8Array(base64); | ||
return new Response(decoded, { | ||
headers: { | ||
'content-type': contentType, | ||
'content-length': decoded.byteLength | ||
} | ||
}); | ||
} | ||
} catch (e) { | ||
// not robust enough yet to care about these errors | ||
} | ||
return null; | ||
}; | ||
|
||
module.exports = staticFetch; |
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,38 @@ | ||
const {test} = require('tap'); | ||
const staticFetch = require('../../src/util/tw-static-fetch'); | ||
|
||
test('fetch simple base64', t => { | ||
const res = staticFetch('data:text/plain;base64,VGVzdGluZyB0ZXN0aW5nIDEyMw=='); | ||
res.text().then(text => { | ||
t.equal(text, 'Testing testing 123'); | ||
t.equal(res.status, 200); | ||
t.equal(res.ok, true); | ||
t.equal(res.headers.get('content-type'), 'text/plain'); | ||
t.equal(res.headers.get('content-length'), '19'); | ||
t.end(); | ||
}); | ||
}); | ||
|
||
test('fetch base64 with all possible bytes', t => { | ||
// eslint-disable-next-line max-len | ||
const res = staticFetch('Data:Application/Octet-Stream;BASE64,AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=='); | ||
res.arrayBuffer().then(buffer => { | ||
t.same(Array.from(new Uint8Array(buffer)), Array(256) | ||
.fill() | ||
.map((_, index) => index) | ||
); | ||
t.equal(res.headers.get('content-type'), 'application/octet-stream'); | ||
t.equal(res.headers.get('content-length'), '256'); | ||
t.end(); | ||
}); | ||
}); | ||
|
||
test('fetch not data:', t => { | ||
t.equal(staticFetch('blob:https://turbowarp.org/54346944-16cf-4ce9-aed4-e1df8ad0d779'), null); | ||
t.equal(staticFetch('https://example.com/'), null); | ||
t.equal(staticFetch('http://example.com/'), null); | ||
t.equal(staticFetch('file:///etc/hosts'), null); | ||
t.equal(staticFetch('oegirjdf'), null); | ||
t.equal(staticFetch(''), null); | ||
t.end(); | ||
}); |