Skip to content

Commit

Permalink
fix: scramjet implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
QuiteAFancyEmerald committed Dec 19, 2024
1 parent 214716e commit f7665d8
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 55 deletions.
101 changes: 98 additions & 3 deletions proxyServiceValidator.js
Original file line number Diff line number Diff line change
Expand Up @@ -312,12 +312,107 @@ xx xx
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 ultravioletPassed = await testUltraviolet();
const scramjetPassed = await testScramjet();

if (rammerheadPassed && ultravioletPassed) {
console.log('Both tests passed.');
if (rammerheadPassed && ultravioletPassed && scramjetPassed) {
console.log('All proxy endpoint tests passed.');
process.exitCode = 0;
} else {
console.error('Tests failed.');
Expand Down
125 changes: 75 additions & 50 deletions views/assets/js/register-sw.js
Original file line number Diff line number Diff line change
@@ -1,99 +1,124 @@
// Encase everything in a new scope so that variables are not accidentally
// attached to the global scope.
(() => {
const stockSW = '/uv/sw.js',
blacklistSW = '/uv/sw-blacklist.js',
swAllowedHostnames = ['localhost', '127.0.0.1'],
connection = new BareMux.BareMuxConnection('/baremux/worker.js'),
wispUrl =
(location.protocol === 'https:' ? 'wss' : 'ws') +
'://' +
location.host +
'/wisp/',
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,
},
}),
// Proxy configuration
proxyUrl = 'socks5h://localhost:9050', // Replace with your TOR proxy URL (or any)
proxyUrl = 'socks5h://localhost:9050', // Replace with your TOR proxy URL
transports = {
epoxy: '/epoxy/index.mjs',
libcurl: '/libcurl/index.mjs',
bare: '/baremux/index.mjs',
},
// The following two variables are copied and pasted here from csel.js.
readCookie = async (name) => {
// Get the first cookie that has the same name.
for (let cookie of document.cookie.split('; '))
if (!cookie.indexOf(name + '='))
// Return the cookie's stored content.
for (let cookie of document.cookie.split('; ')) {
if (!cookie.indexOf(name + '=')) {
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)
? 'epoxy'
: 'libcurl';

transports.default = transports[defaultMode];

// Prevent the transports object from accidentally being edited.

Object.freeze(transports);


const waitForScramjetController = () =>
new Promise((resolve) => {
const interval = setInterval(() => {
if (typeof ScramjetController !== 'undefined') {
clearInterval(interval);
resolve();
}
}, 50);
});

const registerSW = async () => {
if (!navigator.serviceWorker) {
if (
location.protocol !== 'https:' &&
!swAllowedHostnames.includes(location.hostname)
)
throw new Error('Service workers cannot be registered without https.');

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 =
transports[await readCookie('HBTransport')] || transports.default;
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;

console.log('Using Onion Proxy:', proxyUrl);
}

console.log('Transport mode:', transportMode);

const connection = new BareMux.BareMuxConnection('/baremux/worker.js');
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(),
usedSW =
(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)
if (
registration.active &&
new URL(registration.active.scriptURL).pathname !==
new URL(usedSW, location.origin).pathname
)
await registration.unregister();

await navigator.serviceWorker.register(usedSW);
};

// Register the service worker
registerSW();
scramjet.init("/scram/scramjet.sw.js");
})();
const initializeScramjet = async () => {
try {

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();
})();
1 change: 1 addition & 0 deletions views/pages/frame.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

<body>
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
<script src="/scram/scramjet.controller.js"></script>
<iframe id="frame" allow="fullscreen" autofocus></iframe>
<script>
document.getElementById('frame').src = localStorage.getItem('huframesrc');
Expand Down
3 changes: 1 addition & 2 deletions views/pages/proxnav/scramjet.html
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,7 @@ <h3>More Information:</h3>
</div>
<div id="footer" class="fullwidth"><!--FOOTER--></div>
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
<script src="/scram/scramjet.controller.js" defer></script>
<script src="/assets/js/register-sw.js" defer></script>
<script src="/scram/scramjet.controller.js"></script>
<script src="assets/js/common.js"></script>
<script src="assets/js/csel.js"></script>
<script src="{{src}}"></script>
Expand Down
1 change: 1 addition & 0 deletions views/pages/proxnav/ultraviolet.html
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ <h3>More Information:</h3>
</div>
<div id="footer" class="fullwidth"><!--FOOTER--></div>
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
<script src="/scram/scramjet.controller.js"></script>
<script src="assets/js/common.js"></script>
<script src="assets/js/csel.js"></script>
<script src="{{src}}"></script>
Expand Down

0 comments on commit f7665d8

Please sign in to comment.