mirror of
https://github.com/QuiteAFancyEmerald/Holy-Unblocker.git
synced 2025-05-12 11:30:01 -04:00
fix: scramjet implementation
This commit is contained in:
parent
214716e28c
commit
f7665d88ef
5 changed files with 176 additions and 55 deletions
|
@ -312,12 +312,107 @@ xx xx
|
||||||
return uvTestPassed;
|
return uvTestPassed;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Run tests for Rammerhead and Ultraviolet.
|
const testScramjet = async () => {
|
||||||
|
const omniboxId = 'pr-sj',
|
||||||
|
errorPrefix = 'failure',
|
||||||
|
// For the hacky URL test further below, use the URL page's EXACT title.
|
||||||
|
website = Object.freeze({
|
||||||
|
path: 'example.com',
|
||||||
|
title: 'Example Domain',
|
||||||
|
});
|
||||||
|
await page.goto('http://localhost:8080/scramjet');
|
||||||
|
const generatedUrl = await page.evaluate(
|
||||||
|
generateUrl,
|
||||||
|
omniboxId,
|
||||||
|
website.path,
|
||||||
|
errorPrefix
|
||||||
|
);
|
||||||
|
|
||||||
|
const testResults = await page.evaluate(
|
||||||
|
async (generatedUrl, pageTitle) => {
|
||||||
|
const results = [{}, {}];
|
||||||
|
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
const waitForDocument = () => {
|
||||||
|
if (document.readyState === 'complete') resolve();
|
||||||
|
else window.addEventListener('load', resolve);
|
||||||
|
},
|
||||||
|
// Wait until a service worker is registered before continuing.
|
||||||
|
// Also check again to make sure the document is loaded.
|
||||||
|
waitForWorker = async () => {
|
||||||
|
setTimeout(async () => {
|
||||||
|
(await navigator.serviceWorker.getRegistrations()).length > 0
|
||||||
|
? waitForDocument()
|
||||||
|
: waitForWorker();
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
waitForWorker();
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
results[0].scramjet = generatedUrl;
|
||||||
|
|
||||||
|
// Test to see if the document title for example.com has loaded,
|
||||||
|
// by appending an IFrame to the document and grabbing its content.
|
||||||
|
const testGeneratedUrlHacky = async (url) => {
|
||||||
|
const exampleIFrame = document.createElement('iframe');
|
||||||
|
const waitForDocument = new Promise((resolve) => {
|
||||||
|
document.documentElement.appendChild(exampleIFrame);
|
||||||
|
exampleIFrame.addEventListener('load', () => {
|
||||||
|
resolve(
|
||||||
|
exampleIFrame.contentWindow.document.title === pageTitle
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Give 10 seconds for the IFrame to load before manually checking.
|
||||||
|
const timeout = new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve(
|
||||||
|
exampleIFrame.contentWindow.document.title === pageTitle
|
||||||
|
);
|
||||||
|
}, 10000);
|
||||||
|
});
|
||||||
|
|
||||||
|
exampleIFrame.src = url;
|
||||||
|
exampleIFrame.style.display = 'none';
|
||||||
|
return await Promise.race([waitForDocument, timeout]);
|
||||||
|
};
|
||||||
|
|
||||||
|
results[1].sjTestPassed =
|
||||||
|
!!results[0].scramjet.indexOf(errorPrefix) &&
|
||||||
|
(await testGeneratedUrlHacky(results[0].scramjet));
|
||||||
|
} catch (e) {
|
||||||
|
results[0].scramjet = errorPrefix + ': ' + e.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
},
|
||||||
|
generatedUrl,
|
||||||
|
website.title,
|
||||||
|
errorPrefix
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('Scramjet test results:', testResults[0]);
|
||||||
|
const sjTestPassed =
|
||||||
|
testResults[0].scramjet &&
|
||||||
|
testResults[0].scramjet !== 'failure' &&
|
||||||
|
testResults[1].scramjet;
|
||||||
|
console.log(
|
||||||
|
'Scramjet test result:',
|
||||||
|
sjTestPassed ? 'success' : 'failure'
|
||||||
|
);
|
||||||
|
return sjTestPassed;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Run tests for Rammerhead, Ultraviolet and Scramjet
|
||||||
const rammerheadPassed = await testRammerhead();
|
const rammerheadPassed = await testRammerhead();
|
||||||
const ultravioletPassed = await testUltraviolet();
|
const ultravioletPassed = await testUltraviolet();
|
||||||
|
const scramjetPassed = await testScramjet();
|
||||||
|
|
||||||
if (rammerheadPassed && ultravioletPassed) {
|
if (rammerheadPassed && ultravioletPassed && scramjetPassed) {
|
||||||
console.log('Both tests passed.');
|
console.log('All proxy endpoint tests passed.');
|
||||||
process.exitCode = 0;
|
process.exitCode = 0;
|
||||||
} else {
|
} else {
|
||||||
console.error('Tests failed.');
|
console.error('Tests failed.');
|
||||||
|
|
|
@ -1,56 +1,43 @@
|
||||||
// Encase everything in a new scope so that variables are not accidentally
|
|
||||||
// attached to the global scope.
|
|
||||||
(() => {
|
(() => {
|
||||||
const stockSW = '/uv/sw.js',
|
const stockSW = '/uv/sw.js',
|
||||||
blacklistSW = '/uv/sw-blacklist.js',
|
blacklistSW = '/uv/sw-blacklist.js',
|
||||||
swAllowedHostnames = ['localhost', '127.0.0.1'],
|
swAllowedHostnames = ['localhost', '127.0.0.1'],
|
||||||
connection = new BareMux.BareMuxConnection('/baremux/worker.js'),
|
|
||||||
wispUrl =
|
wispUrl =
|
||||||
(location.protocol === 'https:' ? 'wss' : 'ws') +
|
(location.protocol === 'https:' ? 'wss' : 'ws') +
|
||||||
'://' +
|
'://' +
|
||||||
location.host +
|
location.host +
|
||||||
'/wisp/',
|
'/wisp/',
|
||||||
scramjet = new ScramjetController({
|
proxyUrl = 'socks5h://localhost:9050', // Replace with your TOR proxy URL
|
||||||
prefix: "/scram/service/",
|
|
||||||
files: {
|
|
||||||
wasm: "/scram/scramjet.wasm.js",
|
|
||||||
worker: "/scram/scramjet.worker.js",
|
|
||||||
client: "/scram/scramjet.client.js",
|
|
||||||
shared: "/scram/scramjet.shared.js",
|
|
||||||
sync: "/scram/scramjet.sync.js"
|
|
||||||
},
|
|
||||||
flags: {
|
|
||||||
serviceworkers: true,
|
|
||||||
syncxhr: true,
|
|
||||||
scramitize: true,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
// Proxy configuration
|
|
||||||
proxyUrl = 'socks5h://localhost:9050', // Replace with your TOR proxy URL (or any)
|
|
||||||
transports = {
|
transports = {
|
||||||
epoxy: '/epoxy/index.mjs',
|
epoxy: '/epoxy/index.mjs',
|
||||||
libcurl: '/libcurl/index.mjs',
|
libcurl: '/libcurl/index.mjs',
|
||||||
bare: '/baremux/index.mjs',
|
bare: '/baremux/index.mjs',
|
||||||
},
|
},
|
||||||
// The following two variables are copied and pasted here from csel.js.
|
|
||||||
readCookie = async (name) => {
|
readCookie = async (name) => {
|
||||||
// Get the first cookie that has the same name.
|
for (let cookie of document.cookie.split('; ')) {
|
||||||
for (let cookie of document.cookie.split('; '))
|
if (!cookie.indexOf(name + '=')) {
|
||||||
if (!cookie.indexOf(name + '='))
|
|
||||||
// Return the cookie's stored content.
|
|
||||||
return decodeURIComponent(cookie.slice(name.length + 1));
|
return decodeURIComponent(cookie.slice(name.length + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// Sets the default transport mode based on the browser. Firefox is not
|
|
||||||
// supported by epoxy yet, which is why this is implemented.
|
|
||||||
defaultMode = /(?:Chrome|AppleWebKit)\//.test(navigator.userAgent)
|
defaultMode = /(?:Chrome|AppleWebKit)\//.test(navigator.userAgent)
|
||||||
? 'epoxy'
|
? 'epoxy'
|
||||||
: 'libcurl';
|
: 'libcurl';
|
||||||
|
|
||||||
transports.default = transports[defaultMode];
|
transports.default = transports[defaultMode];
|
||||||
|
|
||||||
// Prevent the transports object from accidentally being edited.
|
|
||||||
Object.freeze(transports);
|
Object.freeze(transports);
|
||||||
|
|
||||||
|
const waitForScramjetController = () =>
|
||||||
|
new Promise((resolve) => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
if (typeof ScramjetController !== 'undefined') {
|
||||||
|
clearInterval(interval);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
|
|
||||||
const registerSW = async () => {
|
const registerSW = async () => {
|
||||||
if (!navigator.serviceWorker) {
|
if (!navigator.serviceWorker) {
|
||||||
if (
|
if (
|
||||||
|
@ -58,30 +45,32 @@
|
||||||
!swAllowedHostnames.includes(location.hostname)
|
!swAllowedHostnames.includes(location.hostname)
|
||||||
)
|
)
|
||||||
throw new Error('Service workers cannot be registered without https.');
|
throw new Error('Service workers cannot be registered without https.');
|
||||||
|
|
||||||
throw new Error("Your browser doesn't support service workers.");
|
throw new Error("Your browser doesn't support service workers.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the user has changed the transport mode, use that over the default.
|
// Set the transport mode
|
||||||
const transportMode =
|
const transportMode =
|
||||||
transports[await readCookie('HBTransport')] || transports.default;
|
transports[await readCookie('HBTransport')] || transports.default;
|
||||||
let transportOptions = { wisp: wispUrl };
|
let transportOptions = { wisp: wispUrl };
|
||||||
|
|
||||||
// Only use Tor with the proxy if the user has enabled it in settings.
|
if ((await readCookie('HBUseOnion')) === 'true') {
|
||||||
if ((await readCookie('HBUseOnion')) === 'true')
|
|
||||||
transportOptions.proxy = proxyUrl;
|
transportOptions.proxy = proxyUrl;
|
||||||
|
console.log('Using Onion Proxy:', proxyUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Transport mode:', transportMode);
|
||||||
|
|
||||||
|
const connection = new BareMux.BareMuxConnection('/baremux/worker.js');
|
||||||
await connection.setTransport(transportMode, [transportOptions]);
|
await connection.setTransport(transportMode, [transportOptions]);
|
||||||
|
|
||||||
/* Choose a service worker to register based on whether or not the user
|
|
||||||
* has adblocking enabled. If the user changes this setting, this script needs
|
|
||||||
* to be reloaded for this to update, such as by refreshing the page.
|
|
||||||
*/
|
|
||||||
const registrations = await navigator.serviceWorker.getRegistrations(),
|
const registrations = await navigator.serviceWorker.getRegistrations(),
|
||||||
usedSW =
|
usedSW =
|
||||||
(await readCookie('HBHideAds')) !== 'false' ? blacklistSW : stockSW;
|
(await readCookie('HBHideAds')) !== 'false' ? blacklistSW : stockSW;
|
||||||
|
|
||||||
// Unregister a service worker if it isn't the one being used.
|
console.log('Service Worker being registered:', usedSW);
|
||||||
|
|
||||||
|
// Unregister outdated service workers
|
||||||
for (const registration of registrations)
|
for (const registration of registrations)
|
||||||
if (
|
if (
|
||||||
registration.active &&
|
registration.active &&
|
||||||
|
@ -89,11 +78,47 @@
|
||||||
new URL(usedSW, location.origin).pathname
|
new URL(usedSW, location.origin).pathname
|
||||||
)
|
)
|
||||||
await registration.unregister();
|
await registration.unregister();
|
||||||
|
|
||||||
await navigator.serviceWorker.register(usedSW);
|
await navigator.serviceWorker.register(usedSW);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Register the service worker
|
const initializeScramjet = async () => {
|
||||||
registerSW();
|
try {
|
||||||
scramjet.init("/scram/scramjet.sw.js");
|
|
||||||
})();
|
await waitForScramjetController();
|
||||||
|
|
||||||
|
const scramjet = new ScramjetController({
|
||||||
|
prefix: '/scram/service/',
|
||||||
|
files: {
|
||||||
|
wasm: '/scram/scramjet.wasm.js',
|
||||||
|
worker: '/scram/scramjet.worker.js',
|
||||||
|
client: '/scram/scramjet.client.js',
|
||||||
|
shared: '/scram/scramjet.shared.js',
|
||||||
|
sync: '/scram/scramjet.sync.js',
|
||||||
|
},
|
||||||
|
flags: {
|
||||||
|
serviceworkers: true,
|
||||||
|
syncxhr: true,
|
||||||
|
scramitize: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Initializing ScramjetController');
|
||||||
|
scramjet.init('/scram/scramjet.sw.js');
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Scramjet initialization failed:', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialize = async () => {
|
||||||
|
try {
|
||||||
|
await registerSW();
|
||||||
|
|
||||||
|
await initializeScramjet();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Initialization failed:', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
initialize();
|
||||||
|
})();
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
||||||
|
<script src="/scram/scramjet.controller.js"></script>
|
||||||
<iframe id="frame" allow="fullscreen" autofocus></iframe>
|
<iframe id="frame" allow="fullscreen" autofocus></iframe>
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('frame').src = localStorage.getItem('huframesrc');
|
document.getElementById('frame').src = localStorage.getItem('huframesrc');
|
||||||
|
|
|
@ -162,8 +162,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="footer" class="fullwidth"><!--FOOTER--></div>
|
<div id="footer" class="fullwidth"><!--FOOTER--></div>
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
||||||
<script src="/scram/scramjet.controller.js" defer></script>
|
<script src="/scram/scramjet.controller.js"></script>
|
||||||
<script src="/assets/js/register-sw.js" defer></script>
|
|
||||||
<script src="assets/js/common.js"></script>
|
<script src="assets/js/common.js"></script>
|
||||||
<script src="assets/js/csel.js"></script>
|
<script src="assets/js/csel.js"></script>
|
||||||
<script src="{{src}}"></script>
|
<script src="{{src}}"></script>
|
||||||
|
|
|
@ -104,6 +104,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="footer" class="fullwidth"><!--FOOTER--></div>
|
<div id="footer" class="fullwidth"><!--FOOTER--></div>
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
||||||
|
<script src="/scram/scramjet.controller.js"></script>
|
||||||
<script src="assets/js/common.js"></script>
|
<script src="assets/js/common.js"></script>
|
||||||
<script src="assets/js/csel.js"></script>
|
<script src="assets/js/csel.js"></script>
|
||||||
<script src="{{src}}"></script>
|
<script src="{{src}}"></script>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue