mirror of
https://github.com/QuiteAFancyEmerald/Holy-Unblocker.git
synced 2025-05-13 03:50:02 -04:00
Added corrosion, removed alloy, and added myself to the credits
This commit is contained in:
parent
14f982cad2
commit
961b4ad212
18 changed files with 26 additions and 1281 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -29,3 +29,6 @@
|
||||||
[submodule "views/archive/bunker"]
|
[submodule "views/archive/bunker"]
|
||||||
path = views/archive/bunker
|
path = views/archive/bunker
|
||||||
url = https://github.com/stewpidtnlvr/The-Bunker-Offline
|
url = https://github.com/stewpidtnlvr/The-Bunker-Offline
|
||||||
|
[submodule "src/Corrosion"]
|
||||||
|
path = src/Corrosion
|
||||||
|
url = https://github.com/titaniumnetwork-dev/Corrosion/
|
||||||
|
|
20
app.js
20
app.js
|
@ -4,7 +4,7 @@
|
||||||
* MIT license: http://opensource.org/licenses/MIT
|
* MIT license: http://opensource.org/licenses/MIT
|
||||||
* ----------------------------------------------- */
|
* ----------------------------------------------- */
|
||||||
const
|
const
|
||||||
alloy = require('./src/alloyproxy'),
|
corrosion = require('./src/Corrosion'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
config = require('./config.json'),
|
config = require('./config.json'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
|
@ -108,23 +108,19 @@ function tryReadFile(file) {
|
||||||
return fs.existsSync(file) ? fs.readFileSync(file, 'utf8') : text404;
|
return fs.existsSync(file) ? fs.readFileSync(file, 'utf8') : text404;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local alloy proxy
|
// Local corrosion proxy
|
||||||
const localAlloy = new alloy({
|
const localCorrosion = new corrosion({
|
||||||
prefix: '/fetch/',
|
prefix: '/fetch/',
|
||||||
error: (proxy) => { proxy.res.send(tryReadFile(path.normalize(__dirname + '/views/error.html')).replace('%ERR%', proxy.error.info.message.replace(/<|>/g, ''))); }, // Doing replace functions on "<" and ">" to prevent XSS.
|
ws: true,
|
||||||
request: [],
|
codec: 'plain'
|
||||||
response: [],
|
|
||||||
injection: true
|
|
||||||
});
|
});
|
||||||
app.use(localAlloy.app);
|
|
||||||
localAlloy.ws(server);
|
|
||||||
|
|
||||||
/* Querystring Navigation */
|
/* Querystring Navigation */
|
||||||
app.get('/', async(req, res) => res.send(insertAll(tryReadFile(path.normalize(__dirname + '/views/' + (['/', '/?'].includes(req.url) ? siteIndex : pages[Object.keys(req.query)[0]]))))));
|
app.get('/', async(req, res) => res.send(insertAll(tryReadFile(path.normalize(__dirname + '/views/' + (['/', '/?'].includes(req.url) ? siteIndex : pages[Object.keys(req.query)[0]]))))));
|
||||||
|
|
||||||
/* Static Files Served */
|
/* Static Files Served */
|
||||||
app.use(express.static(path.normalize(__dirname + '/views')));
|
app.use(express.static(path.normalize(__dirname + '/views')));
|
||||||
app.use((req, res) => res.status(404, res.send(insertAll(text404))));
|
app.use((req, res) => {if (req.url.startsWith(localCorrosion.prefix)) return localCorrosion.request(req, res); res.status(404, res.send(insertAll(text404)))});
|
||||||
|
|
||||||
server.listen(port);
|
server.listen(port);
|
||||||
console.log('Holy Unblocker is listening on port ' + port + '. This is simply a public for Holy Unblocker. Certain functions may not work properly.');
|
console.log('Holy Unblocker is listening on port ' + port + '. This is simply a public for Holy Unblocker. Certain functions may not work properly.');
|
||||||
|
|
1
src/Corrosion
Submodule
1
src/Corrosion
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 665c8b74838393e783b3ce61ae341e4b739100f1
|
|
@ -1,156 +0,0 @@
|
||||||
# AlloyProxy
|
|
||||||
Module specialized in proxying websites to unblock the web.
|
|
||||||
|
|
||||||
## Table of contents:
|
|
||||||
|
|
||||||
- [Setup](#how-to-use)
|
|
||||||
- [Module Use](#module-use)
|
|
||||||
- [Sample Implementation](#sample-express-application)
|
|
||||||
- [Sample Implementation Extended](#sample-implementation)
|
|
||||||
- [Configurations](#configurations)
|
|
||||||
- [General Use](#general-use)
|
|
||||||
- [Extended Configuration Information](#extended-configuration-information)
|
|
||||||
- [Websocket Proxy Information](#websocket-proxy-information)
|
|
||||||
|
|
||||||
### Module Use
|
|
||||||
|
|
||||||
1. `npm install alloyproxy`
|
|
||||||
|
|
||||||
2. Set all of your configs in the main file for the Node app.
|
|
||||||
|
|
||||||
3. Start up your app and unblock a website at `/prefix/[BASE64 ENCODED WEBSITE ORIGIN]/`. The path of the website does not have to be B64 encoded.
|
|
||||||
|
|
||||||
A good example of what code to use is here using the Express.js framework.
|
|
||||||
|
|
||||||
### Sample Express Application
|
|
||||||
1. Navigate to the `/examples/` folder.
|
|
||||||
|
|
||||||
2. Do the following commands:
|
|
||||||
|
|
||||||
```
|
|
||||||
cd examples/express
|
|
||||||
|
|
||||||
npm install
|
|
||||||
|
|
||||||
npm start
|
|
||||||
```
|
|
||||||
|
|
||||||
The demo application will run at `localhost:8080` by default however the port can be configured in `config.json`.
|
|
||||||
|
|
||||||
The static folder provides you with the base site if you wish to go manual about this.
|
|
||||||
|
|
||||||
### Sample Implementation
|
|
||||||
Add this to your server-side script ex. "app.js".
|
|
||||||
```
|
|
||||||
// Note: make sure you use Alloy before any other Express middleware that sends responses to client or handles POST data.
|
|
||||||
|
|
||||||
const Alloy = require('alloyproxy'),
|
|
||||||
http = require('http'),
|
|
||||||
express = require('express'),
|
|
||||||
app = express();
|
|
||||||
|
|
||||||
const server = http.createServer(app);
|
|
||||||
|
|
||||||
const Unblocker = new Alloy({
|
|
||||||
prefix: '/fetch/',
|
|
||||||
request: [],
|
|
||||||
response: [],
|
|
||||||
injection: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
// The main part of the proxy.
|
|
||||||
|
|
||||||
app.use(Unblocker.app);
|
|
||||||
|
|
||||||
// WebSocket handler.
|
|
||||||
|
|
||||||
Unblocker.ws(server);
|
|
||||||
|
|
||||||
server.listen('8080')
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configurations
|
|
||||||
### General Use
|
|
||||||
|
|
||||||
```
|
|
||||||
prefix: '/prefix/',
|
|
||||||
blocklist: [],
|
|
||||||
// error: (proxy) => { return proxy.res.end('proxy.error.info.message') }, Custom error handling which is optional.
|
|
||||||
request: [], // Add custom functions before request is made or modify the request.
|
|
||||||
response: [], // Add custom functions after the request is made or modify the response.
|
|
||||||
injection: true, // Script injection which is helpful in rewriting window.fetch() and all kinds of client-side JS requests.
|
|
||||||
requestAgent: null, // Set a custom agent to use in the request.
|
|
||||||
// userAgent: Uses the clients "User-Agent" request header by default. More customizable using the "request" option in the configs.
|
|
||||||
localAddress: [] // Neat feature in basic http(s).request() to choose what IP to use to make the request. Will be randomized if there is multiple.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Extended Configuration Information
|
|
||||||
|
|
||||||
To use the "request" and "response" options in the config. You must make a function like this for example.
|
|
||||||
|
|
||||||
```
|
|
||||||
customFunction = (proxy) => {
|
|
||||||
|
|
||||||
if (proxy.url.hostname == 'example.org' && proxy.response.headers['content-type'].startsWith('text/html')) {
|
|
||||||
|
|
||||||
return proxy.sendResponse == proxy.sendResponse.toString().replace(/example/gi, 'cat :3');
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
new Alloy({
|
|
||||||
prefix: '/prefix/',
|
|
||||||
blocklist: [],
|
|
||||||
// error: (proxy) => { return proxy.res.end('proxy.error.info.message') }, Custom error handling which is optional.
|
|
||||||
request: [], // Add custom functions before request is made or modify the request.
|
|
||||||
response: [
|
|
||||||
|
|
||||||
customFunction
|
|
||||||
|
|
||||||
], // Add custom functions after the request is made or modify the response.
|
|
||||||
injection: true, // Script injection which is helpful in rewriting window.fetch() and all kinds of client-side JS requests.
|
|
||||||
requestAgent: null, // Set a custom agent to use in the request.
|
|
||||||
// userAgent: Uses the clients "User-Agent" request header by default. More customizable using the "request" option in the configs.
|
|
||||||
localAddress: [] // Neat feature in basic http(s).request() to choose what IP to use to make the request. Will be randomized if there is multiple.
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
What this will do is when the hostname of a website being accessed is `example.org`. The console sends you "weee :3". If you want a preview of what options you have, heres a list. :)
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
// Basic HTTP functions.
|
|
||||||
|
|
||||||
proxy.req // This is the request option in HTTP servers. If Express.js is being used, you can use Express.js functions.
|
|
||||||
proxy.res // This is the response option in HTTP servers. If Express.js is being used, you can use Express.js functions.
|
|
||||||
proxy.next() // This is only avaliable in Express.js . If used in native HTTP, the app will display blank text as a filler.
|
|
||||||
|
|
||||||
// Request
|
|
||||||
|
|
||||||
proxy.request.headers // A modified version of the client's request headers used in sending the request.
|
|
||||||
proxy.request.method // The clients request method.
|
|
||||||
proxy.request.body // The POST body of a POST / PATCH request.
|
|
||||||
|
|
||||||
// Response
|
|
||||||
|
|
||||||
proxy.response // The entire response of the website. Contains headers, JSON / text response, and all Node.js http(s).request() response data.
|
|
||||||
proxy.response.headers // Response headers the website gave back. Is modified to filter out bad headers, and rewrite "Set-Cookie" header.
|
|
||||||
proxy.sendResponse // The modified response buffer the website gave back. You can modify it in anyway you desire. :)
|
|
||||||
|
|
||||||
// Errors
|
|
||||||
|
|
||||||
proxy.error.status // Outputs "true" when theres an error.
|
|
||||||
proxy.error.info // Gives information about an error.
|
|
||||||
proxy.error.info.code // Gives error code. Error codes such as "ENOTFOUND" mean a website could not be found. "BLOCKED" means a website is blocked.
|
|
||||||
proxy.error.info.message // Gives error message.
|
|
||||||
proxy.blocked.status // Outputs "true" when a filtered hostname is detected.
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## Websocket Proxy Information
|
|
||||||
|
|
||||||
Alloy does come with a built in websocket proxy. To use it, you must have an HTTP server already defined. The example of using Alloy as Express middleware already uses the websocket proxy.
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
// Note: make sure you use Alloy before any other Express middleware that sends responses to client or handles POST data.
|
|
||||||
|
|
||||||
const Alloy = require('alloyproxy'),
|
|
||||||
http = require('http'),
|
|
||||||
express = require('express'),
|
|
||||||
app = express();
|
|
||||||
|
|
||||||
const server = http.createServer(app);
|
|
||||||
|
|
||||||
const Unblocker = new Alloy({
|
|
||||||
prefix: '/fetch/',
|
|
||||||
request: [],
|
|
||||||
response: [],
|
|
||||||
injection: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
// The main part of the proxy.
|
|
||||||
|
|
||||||
app.use(Unblocker.app);
|
|
||||||
|
|
||||||
|
|
||||||
// Do your stuff here! :3
|
|
||||||
|
|
||||||
// WebSocket handler.
|
|
||||||
|
|
||||||
Unblocker.ws(server);
|
|
||||||
|
|
||||||
|
|
||||||
server.listen('8080')
|
|
|
@ -1,33 +0,0 @@
|
||||||
module.exports = class {
|
|
||||||
|
|
||||||
constructor(config) {
|
|
||||||
|
|
||||||
// If parts of the config are messing. The parts are filled with placeholders.
|
|
||||||
|
|
||||||
if (!config) config = {};
|
|
||||||
|
|
||||||
if (!config.prefix) config.prefix = '/get/';
|
|
||||||
|
|
||||||
if (!config.prefix.startsWith('/')) config.prefix = '/' + config.prefix;
|
|
||||||
|
|
||||||
if (!config.prefix.endsWith('/')) config.prefix = config.prefix + '/';
|
|
||||||
|
|
||||||
if (!config.blocklist) config.blocklist = [];
|
|
||||||
|
|
||||||
if (!config.request) config.request = [];
|
|
||||||
|
|
||||||
if (!config.response) config.response = [];
|
|
||||||
|
|
||||||
this.config = config;
|
|
||||||
|
|
||||||
// Main proxy.
|
|
||||||
|
|
||||||
this.app = require('./libs/proxy.js')(config);
|
|
||||||
|
|
||||||
// WebSocket Proxy.
|
|
||||||
|
|
||||||
this.ws = (server) => require('./libs/websocket.js')(server, config);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,275 +0,0 @@
|
||||||
const sendRequest = require('./requests.js'),
|
|
||||||
rewrite = require('./rewriting.js'),
|
|
||||||
fs = require('fs'),
|
|
||||||
bodyParser = (req) => {
|
|
||||||
|
|
||||||
return new Promise(resolve => {
|
|
||||||
|
|
||||||
var body = '';
|
|
||||||
|
|
||||||
req.on('data', chunk => {
|
|
||||||
|
|
||||||
body += chunk;
|
|
||||||
|
|
||||||
}).on('end', () => {
|
|
||||||
|
|
||||||
resolve(body);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = (config) => {
|
|
||||||
|
|
||||||
return async (req, res, next) => {
|
|
||||||
|
|
||||||
// To have compatibility with both native Node.js HTTP and Express.js.
|
|
||||||
|
|
||||||
if (typeof next != 'function') next = () => res.end('');
|
|
||||||
|
|
||||||
if (typeof config.injection == 'undefined' || typeof config.injection == 'null') config.injection = true;
|
|
||||||
|
|
||||||
if (req.url.startsWith(config.prefix) && config.injection == true) {
|
|
||||||
|
|
||||||
// Setting up public directory for injection scripts.
|
|
||||||
|
|
||||||
if (req.url.startsWith(`${config.prefix}static/`)) {
|
|
||||||
|
|
||||||
path = req.url.toString().replace(`${config.prefix}static`, '');
|
|
||||||
|
|
||||||
if (path.includes('?')) path = path.split('?').splice(0, 1).join('');
|
|
||||||
|
|
||||||
if (path.includes('#')) path = path.split('#').splice(0, 1).join('');
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
return res.end(fs.readFileSync(__dirname + `/static${path}`, {
|
|
||||||
encoding: 'utf8'
|
|
||||||
}));
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
return res.end('')
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setting configurations for errors, requests, urls, and blocklist.
|
|
||||||
|
|
||||||
var proxy = {
|
|
||||||
|
|
||||||
request: {
|
|
||||||
|
|
||||||
// Defined later on. Uses clients request headers as the headers used when making the request to the server, although its slightly modifed to work.
|
|
||||||
|
|
||||||
headers: {},
|
|
||||||
|
|
||||||
// Using the clients request method as the method used when making the request to the server.0
|
|
||||||
|
|
||||||
method: req.method,
|
|
||||||
|
|
||||||
// When this is true, the response of websites with invalid SSL certs will not be given.
|
|
||||||
|
|
||||||
rejectUnauthorized: false
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
error: {
|
|
||||||
|
|
||||||
status: false,
|
|
||||||
|
|
||||||
info: null
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
blocked: {
|
|
||||||
|
|
||||||
status: false,
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
prefix: config.prefix,
|
|
||||||
|
|
||||||
// Can be used to create extra functions.
|
|
||||||
|
|
||||||
req: req,
|
|
||||||
res: res,
|
|
||||||
next: next,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
try { proxy.url = new URL(rewrite.url(req.url.replace(config.prefix, ''), 'decode')); } catch(err) {
|
|
||||||
|
|
||||||
proxy.error.status = true;
|
|
||||||
|
|
||||||
// Using 404 error as a filler for this.
|
|
||||||
|
|
||||||
proxy.error.info = {
|
|
||||||
|
|
||||||
code: 'ENOTFOUND',
|
|
||||||
message: `Could not make ${req.method} request to "${rewrite.url(req.url.replace(config.prefix, ''), 'decode')}".`
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
if (config.error) return config.error(proxy);
|
|
||||||
|
|
||||||
return res.end(proxy.error.info.message.replace(/</gi, '<‌').replace(/>/gi, '>‌'));
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
proxy.injection = config.injection;
|
|
||||||
|
|
||||||
Object.entries(req.headers).forEach(([header_name, header_value]) => proxy.request.headers[header_name] = header_value);
|
|
||||||
|
|
||||||
delete proxy.request.headers['host'];
|
|
||||||
|
|
||||||
// Rewriting "Referer" and "Origin" headers to be accurate as possible in the request.
|
|
||||||
|
|
||||||
if (proxy.request.headers['referer']) proxy.request.headers['referer'] = rewrite.referer(proxy.request.headers['referer'], proxy)
|
|
||||||
|
|
||||||
if (proxy.request.headers['origin']) proxy.request.headers['origin'] = rewrite.origin(proxy.request.headers['origin'], proxy)
|
|
||||||
|
|
||||||
// Forcing character limit on Cookie header because too many cookies in the header can lead to a "Header Overflow" error. Will most likely be replaced in the future.
|
|
||||||
|
|
||||||
|
|
||||||
if (proxy.request.headers['cookie']) {
|
|
||||||
|
|
||||||
var new_cookie = [],
|
|
||||||
cookie_array = proxy.request.headers['cookie'].split('; ');
|
|
||||||
|
|
||||||
cookie_array.forEach(cookie => {
|
|
||||||
|
|
||||||
cookie_name = cookie.split('=').splice(0, 1).join();
|
|
||||||
|
|
||||||
cookie_value = cookie.split('=').splice(1).join();
|
|
||||||
|
|
||||||
if (proxy.url.hostname.includes(cookie_name.split('@').splice(1).join())) new_cookie.push(cookie_name.split('@').splice(0, 1).join() + '=' + cookie_value);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
proxy.request.headers['cookie'] = new_cookie.join('; ');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// If theres a user agent in the config, use that user agent instead of using the browsers user agent by default.
|
|
||||||
|
|
||||||
if (config.userAgent) proxy.request.headers['user-agent'] = config.useragent;
|
|
||||||
|
|
||||||
if (config.requestAgent) proxy.request['agent'] = config.requestAgent;
|
|
||||||
|
|
||||||
delete proxy.request.headers['accept-encoding'];
|
|
||||||
|
|
||||||
// Getting data from our body parser for HTTP (POST / PATCH) requests.
|
|
||||||
|
|
||||||
if (req.method == 'POST' || req.method == 'PATCH') proxy.request.body = await bodyParser(req);
|
|
||||||
|
|
||||||
config.blocklist.forEach(hostname => {
|
|
||||||
|
|
||||||
if (proxy.url.hostname == hostname) {
|
|
||||||
|
|
||||||
proxy.error.status = true;
|
|
||||||
|
|
||||||
proxy.blocked.status = true;
|
|
||||||
|
|
||||||
proxy.error.info = {
|
|
||||||
|
|
||||||
code: 'BLOCKED',
|
|
||||||
|
|
||||||
message: `Could not make ${req.method} request to "${rewrite.url(req.url.replace(config.prefix, ''), 'decode')}".`
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// If URL hostname has been detected as blocked, the app blocks all further functions and sends a different response to the client.
|
|
||||||
|
|
||||||
if (proxy.blocked.status == true) {
|
|
||||||
|
|
||||||
if (config.error) return config.error(proxy);
|
|
||||||
|
|
||||||
return res.end(proxy.error.info.message.replace(/</gi, '<‌').replace(/>/gi, '>‌'));
|
|
||||||
|
|
||||||
}
|
|
||||||
// In http.request(), there is a feature to choose what IP you want to use when making the request. This is useful when your server has additional IP's.
|
|
||||||
// When there is multiple IP's in the array, the proxy randomizes which one to use. This is useful to bypass Youtube's request checking.
|
|
||||||
|
|
||||||
if (config.localAddress) proxy.request.localAddress = config.localAddress[Math.floor(Math.random() * config.localAddress.length)]
|
|
||||||
|
|
||||||
// Allowing custom functions to be set before the request is made.
|
|
||||||
|
|
||||||
config.request.forEach(customFunction => customFunction(proxy));
|
|
||||||
|
|
||||||
// The request is made to the website, and is awaiting response.
|
|
||||||
|
|
||||||
// Error handling.
|
|
||||||
|
|
||||||
if (!req.url.startsWith(config.prefix + btoa(proxy.url.origin) + '/')) {
|
|
||||||
res.writeHead(307, {
|
|
||||||
Location: config.prefix + btoa(proxy.url.origin) + '/'
|
|
||||||
});
|
|
||||||
return res.end();
|
|
||||||
};
|
|
||||||
|
|
||||||
proxy.response = await sendRequest(proxy.url.href, proxy.request).catch(err => {
|
|
||||||
|
|
||||||
proxy.error.status = true;
|
|
||||||
|
|
||||||
proxy.error.info = {
|
|
||||||
|
|
||||||
code: err.code,
|
|
||||||
|
|
||||||
message: `Could not make ${req.method} request to "${rewrite.url(req.url.replace(config.prefix, ''), 'decode')}".`
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
if (proxy.error.status == true) {
|
|
||||||
|
|
||||||
if (config.error) return config.error(proxy);
|
|
||||||
|
|
||||||
return res.end(proxy.error.info.message.replace(/</gi, '<‌').replace(/>/gi, '>‌'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
proxy.sendResponse = await proxy.response.buffer;
|
|
||||||
|
|
||||||
// Filtering out bad headers, setting redirect locations, and rewriting cookies.
|
|
||||||
|
|
||||||
rewrite.headers(proxy);
|
|
||||||
|
|
||||||
// Setting response status and headers.
|
|
||||||
|
|
||||||
res.writeHead(proxy.response.statusCode, proxy.response.headers);
|
|
||||||
|
|
||||||
// When rewriting, the "Content-Type" header is extracted, and if it matches ("text/html" | "text/css") the response body gets rewritten. But when the request is POST, "Content-Type" is undefined so we set the header to "text/html" which won't effect POST responses.
|
|
||||||
|
|
||||||
if (typeof proxy.response.headers['content-type'] == 'null' || typeof proxy.response.headers['content-type'] == 'undefined') proxy.response.headers['content-type'] = 'text/html';
|
|
||||||
|
|
||||||
// Rewriting body based off of "Content-Type" header to not mess up any images or javascript types.
|
|
||||||
|
|
||||||
if (proxy.response.headers['content-type'].startsWith('text/html') || proxy.response.headers['content-type'].startsWith('text/css')) {
|
|
||||||
|
|
||||||
proxy.sendResponse = rewrite.body(proxy.sendResponse.toString(), proxy)
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Allowing custom functions to be set after response is made and rewritten.
|
|
||||||
|
|
||||||
config.response.forEach(customFunction => customFunction(proxy));
|
|
||||||
|
|
||||||
// Sending response to the client.
|
|
||||||
|
|
||||||
res.end(proxy.sendResponse);
|
|
||||||
|
|
||||||
} else next();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,142 +0,0 @@
|
||||||
const http = require('http'),
|
|
||||||
https = require('https'),
|
|
||||||
zlib = require('zlib');
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = (url, options) => {
|
|
||||||
|
|
||||||
|
|
||||||
if (!options) options = {};
|
|
||||||
|
|
||||||
var request = {};
|
|
||||||
|
|
||||||
request.options = options;
|
|
||||||
|
|
||||||
var protocol;
|
|
||||||
|
|
||||||
if (url.startsWith('https://')) {
|
|
||||||
protocol = https
|
|
||||||
} else protocol = http;
|
|
||||||
|
|
||||||
return new Promise((resolve, error) => {
|
|
||||||
|
|
||||||
var req = protocol.request(url, request.options, res => {
|
|
||||||
|
|
||||||
var response = res;
|
|
||||||
|
|
||||||
response.json = new Promise(resolve => {
|
|
||||||
|
|
||||||
var body = '',
|
|
||||||
json = '';
|
|
||||||
|
|
||||||
res.on('data', chunk => body += chunk);
|
|
||||||
|
|
||||||
res.on('end', () => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
json = JSON.parse(body);
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
|
|
||||||
json = {};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(json);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
response.text = new Promise(resolve => {
|
|
||||||
|
|
||||||
var data = '',
|
|
||||||
text = '';
|
|
||||||
|
|
||||||
res.on('data', chunk => data = chunk.toString());
|
|
||||||
|
|
||||||
res.on('end', () => {
|
|
||||||
text = data;
|
|
||||||
resolve(text);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
response.buffer = new Promise(resolve => {
|
|
||||||
|
|
||||||
var buffer = [];
|
|
||||||
|
|
||||||
res.on('data', binary => {
|
|
||||||
|
|
||||||
buffer.push(binary)
|
|
||||||
|
|
||||||
}).on('end', () => {
|
|
||||||
|
|
||||||
buffer = Buffer.concat(buffer)
|
|
||||||
|
|
||||||
switch (res.headers['content-encoding']) {
|
|
||||||
|
|
||||||
case 'gzip':
|
|
||||||
case 'x-gzip':
|
|
||||||
|
|
||||||
zlib.gunzip(buffer, (err, buffer) => {
|
|
||||||
|
|
||||||
resolve(buffer);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'deflate':
|
|
||||||
case 'x-deflate':
|
|
||||||
|
|
||||||
zlib.inflate(buffer, (err, buffer) => {
|
|
||||||
|
|
||||||
resolve(buffer);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'br':
|
|
||||||
|
|
||||||
zlib.BrotliDecompress(buffer, (err, buffer) => {
|
|
||||||
|
|
||||||
resolve(buffer);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
resolve(buffer);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
resolve(response);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
req.on('error', err => {
|
|
||||||
|
|
||||||
error(err);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if (options.body) {
|
|
||||||
req.write(options.body);
|
|
||||||
req.end();
|
|
||||||
} else req.end();
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,187 +0,0 @@
|
||||||
// Base64 encoding and decoding functions.
|
|
||||||
btoa = (str) => {
|
|
||||||
|
|
||||||
str = new Buffer.from(str).toString('base64');
|
|
||||||
|
|
||||||
return str;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
atob = (str) => {
|
|
||||||
|
|
||||||
str = new Buffer.from(str, 'base64').toString('utf-8');
|
|
||||||
|
|
||||||
return str;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Rewriting URL's.
|
|
||||||
|
|
||||||
url = (url, type) => {
|
|
||||||
|
|
||||||
if (url.startsWith('//')) url = 'http:' + url;
|
|
||||||
|
|
||||||
var origin, path;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
|
|
||||||
case 'decode':
|
|
||||||
|
|
||||||
origin = atob(url.split('/').splice(0, 1).join('/'));
|
|
||||||
|
|
||||||
path = '/' + url.split('/').splice(1).join('/');
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
origin = btoa(url.split('/').splice(0, 3).join('/'));
|
|
||||||
|
|
||||||
path = '/' + url.split('/').splice(3).join('/');
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return origin + path;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Rewriting response buffers to send to client.
|
|
||||||
|
|
||||||
body = (buffer, config) => {
|
|
||||||
|
|
||||||
|
|
||||||
proxified_body = buffer.toString()
|
|
||||||
.replace(/integrity="(.*?)"/gi, '')
|
|
||||||
.replace(/nonce="(.*?)"/gi, '')
|
|
||||||
.replace(/(href|src|poster|data|action|srcset|data-src|data-href)="\/\/(.*?)"/gi, `$1` + `="http://` + `$2` + `"`)
|
|
||||||
.replace(/(href|src|poster|data|action|srcset|data-src|data-href)='\/\/(.*?)'/gi, `$1` + `='http://` + `$2` + `'`)
|
|
||||||
.replace(/(href|src|poster|data|action|srcset|data-src|data-href)="\/(.*?)"/gi, `$1` + `="${config.prefix}${btoa(config.url.origin)}/` + `$2` + `"`)
|
|
||||||
.replace(/(href|src|poster|data|action|srcset|data-src|data-href)='\/(.*?)'/gi, `$1` + `='${config.prefix}${btoa(config.url.origin)}/` + `$2` + `'`)
|
|
||||||
.replace(/(href|src|poster|data|action|srcset|data-src|data-href)="(https:\/\/|http:\/\/)(.*?)"/gi, str => {
|
|
||||||
|
|
||||||
attribute = str.split('=').splice(0, 1).join('');
|
|
||||||
|
|
||||||
href = str.replace(`${attribute}=`, '').slice(1).slice(0, -1);
|
|
||||||
|
|
||||||
return `${attribute}="${config.prefix}${url(href)}"`;
|
|
||||||
|
|
||||||
})
|
|
||||||
.replace(/(href|src|poster|data|action|srcset|data-src|data-href)='(https:\/\/|http:\/\/)(.*?)'/gi, str => {
|
|
||||||
|
|
||||||
attribute = str.split('=').splice(0, 1).join('');
|
|
||||||
|
|
||||||
href = str.replace(`${attribute}=`, '').slice(1).slice(0, -1);
|
|
||||||
|
|
||||||
return `${attribute}='${config.prefix}${url(href)}'`;
|
|
||||||
|
|
||||||
})
|
|
||||||
.replace(/(window|document).location.href/gi, `"${config.url.href}"`)
|
|
||||||
.replace(/(window|document).location.hostname/gi, `"${config.url.hostname}"`)
|
|
||||||
.replace(/(window|document).location.pathname/gi, `"${config.url.path}"`)
|
|
||||||
.replace(/location.href/gi, `"${config.url.href}"`)
|
|
||||||
.replace(/location.hostname/gi, `"${config.url.hostname}"`)
|
|
||||||
.replace(/location.pathname/gi, `"${config.url.path}"`)
|
|
||||||
.replace(/url\("\/\/(.*?)"\)/gi, `url("http://` + `$1` + `")`)
|
|
||||||
.replace(/url\('\/\/(.*?)'\)/gi, `url('http://` + `$1` + `')`)
|
|
||||||
.replace(/url\(\/\/(.*?)\)/gi, `url(http://` + `$1` + `)`)
|
|
||||||
.replace(/url\("\/(.*?)"\)/gi, `url("${config.prefix}${btoa(config.url.origin)}/` + `$1` + `")`)
|
|
||||||
.replace(/url\('\/(.*?)'\)/gi, `url('${config.prefix}${btoa(config.url.origin)}/` + `$1` + `')`)
|
|
||||||
.replace(/url\(\/(.*?)\)/gi, `url(${config.prefix}${btoa(config.url.origin)}/` + `$1` + `)`);
|
|
||||||
|
|
||||||
if (config.injection == true) {
|
|
||||||
|
|
||||||
proxified_body = proxified_body.replace(/<head(.*?)>/gi, `<head` + `$1` + `> \n <script src="${config.prefix}static/inject.js" id="_alloy_data" prefix="${config.prefix}" url="${btoa(config.url.href)}"></script>`);
|
|
||||||
|
|
||||||
if (!proxified_body.match(/<head(.*?)>/gi)) proxified_body = proxified_body.replace(/<html(.*?)>/gi, `<html` + `$1` + `> \n <script src="${config.prefix}static/inject.js" id="_alloy_data" prefix="${config.prefix}" url="${btoa(config.url.href)}"></script>`);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
return proxified_body;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Rewriting the "Origin" request header.
|
|
||||||
|
|
||||||
origin = (origin, config) => {
|
|
||||||
|
|
||||||
origin = '/' + String(origin).split('/').splice(3).join('/');
|
|
||||||
|
|
||||||
origin = url(origin.replace(config.prefix, ''), 'decode');
|
|
||||||
|
|
||||||
if (origin.startsWith('https://') || origin.startsWith('http://')) {
|
|
||||||
|
|
||||||
origin = origin.split('/').splice(0, 3).join('/');
|
|
||||||
|
|
||||||
} else origin = config.url.origin;
|
|
||||||
|
|
||||||
return origin;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Rewriting the "Referer" request header.
|
|
||||||
|
|
||||||
referer = (referer, config) => {
|
|
||||||
|
|
||||||
referer = '/' + String(referer).split('/').splice(3).join('/');
|
|
||||||
|
|
||||||
referer = url(referer.replace(config.prefix, ''), 'decode');
|
|
||||||
|
|
||||||
if (referer.startsWith('https://') || referer.startsWith('http://')) {
|
|
||||||
referer = referer;
|
|
||||||
|
|
||||||
} else referer = config.url.href;
|
|
||||||
|
|
||||||
return referer;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
headers = (proxy) => {
|
|
||||||
|
|
||||||
Object.entries(proxy.response.headers).forEach(([header_name, header_value]) => {
|
|
||||||
|
|
||||||
if (header_name == 'location') {
|
|
||||||
proxy.response.statusCode = 308;
|
|
||||||
proxy.response.headers[header_name] = proxy.prefix + url(header_value);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (header_name == 'set-cookie') {
|
|
||||||
|
|
||||||
var array = [];
|
|
||||||
|
|
||||||
header_value.forEach(cookie => {
|
|
||||||
|
|
||||||
cookie = cookie.replace(/Domain=(.*?);/gi, `Domain=` + proxy.req.headers['host'] + ';').replace(/(.*?)=(.*?);/, '$1' + '@' + proxy.url.hostname + `=` + '$2' + ';');
|
|
||||||
|
|
||||||
array.push(cookie);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
proxy.response.headers[header_name] = array;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
if (header_name.startsWith('content-encoding') || header_name.startsWith('x-') || header_name.startsWith('cf-') || header_name.startsWith('strict-transport-security') || header_name.startsWith('content-security-policy') || header_name.startsWith('content-length')) {
|
|
||||||
|
|
||||||
delete proxy.response.headers[header_name];
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// Setting all our functions to be used in "proxy.js"
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
|
|
||||||
url: url,
|
|
||||||
body: body,
|
|
||||||
origin: origin,
|
|
||||||
referer: referer,
|
|
||||||
headers: headers
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
var alloy_data = document.querySelector('#_alloy_data');
|
|
||||||
|
|
||||||
var prefix = alloy_data.getAttribute('prefix');
|
|
||||||
|
|
||||||
var url = new URL(atob(alloy_data.getAttribute('url')))
|
|
||||||
|
|
||||||
rewrite_url = (str) => {
|
|
||||||
proxied_url = '';
|
|
||||||
if (str.startsWith(window.location.origin + '/') && !str.startsWith(window.location.origin + prefix)) {
|
|
||||||
str = '/' + str.split('/').splice(3).join('/');
|
|
||||||
}
|
|
||||||
if (str.startsWith('//')) {
|
|
||||||
str = 'http:' + str;
|
|
||||||
} else if (str.startsWith('/') && !str.startsWith(prefix)) {
|
|
||||||
str = url.origin + str
|
|
||||||
}
|
|
||||||
if (str.startsWith('https://') || str.startsWith('http://')) {
|
|
||||||
path = "/" + str.split('/').splice(3).join('/');
|
|
||||||
origin = btoa(str.split('/').splice(0, 3).join('/'));
|
|
||||||
return proxied_url = prefix + origin + path
|
|
||||||
} else {
|
|
||||||
proxied_url = str;
|
|
||||||
}
|
|
||||||
return proxied_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let fetch_rewrite = window.fetch; window.fetch = function(url, options) {
|
|
||||||
url = rewrite_url(url);
|
|
||||||
return fetch_rewrite.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
let xml_rewrite = window.XMLHttpRequest.prototype.open;window.XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
|
|
||||||
url = rewrite_url(url);
|
|
||||||
return xml_rewrite.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
let createelement_rewrite = document.createElement; document.createElement = function(tag) {
|
|
||||||
var element = createelement_rewrite.call(document, tag);
|
|
||||||
if (tag.toLowerCase() === 'script' || tag.toLowerCase() === 'iframe' || tag.toLowerCase() === 'embed') {
|
|
||||||
Object.defineProperty(element.__proto__, 'src', {
|
|
||||||
set: function(value) {
|
|
||||||
value = rewrite_url(value)
|
|
||||||
element.setAttribute('src', value)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (tag.toLowerCase() === 'link') {
|
|
||||||
Object.defineProperty(element.__proto__, 'href', {
|
|
||||||
set: function(value) {
|
|
||||||
value = rewrite_url(value)
|
|
||||||
element.setAttribute('href', value)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (tag.toLowerCase() === 'form') {
|
|
||||||
Object.defineProperty(element.__proto__, 'action', {
|
|
||||||
set: function(value) {
|
|
||||||
value = rewrite_url(value)
|
|
||||||
element.setAttribute('action', value)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
let setattribute_rewrite = window.Element.prototype.setAttribute; window.Element.prototype.setAttribute = function(attribute, href) {
|
|
||||||
if (attribute == ('src') || attribute == ('href') || attribute == ('action')) {
|
|
||||||
href = rewrite_url(href)
|
|
||||||
} else href = href;
|
|
||||||
return setattribute_rewrite.apply(this, arguments)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rewriting all incoming websocket request.
|
|
||||||
|
|
||||||
WebSocket = new Proxy(WebSocket, {
|
|
||||||
|
|
||||||
construct(target, args_array) {
|
|
||||||
|
|
||||||
var protocol;
|
|
||||||
|
|
||||||
if (location.protocol == 'https:') { protocol = 'wss://' } else { protocol = 'ws://' }
|
|
||||||
|
|
||||||
args_array[0] = protocol + location.origin.split('/').splice(2).join('/') + prefix + 'ws/' + btoa(args_array[0]);
|
|
||||||
|
|
||||||
return new target(args_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Rewriting incoming pushstate.
|
|
||||||
|
|
||||||
history.pushState = new Proxy(history.pushState, {
|
|
||||||
|
|
||||||
apply: (target, thisArg, args_array) => {
|
|
||||||
|
|
||||||
args_array[2] = rewrite_url(args_array[2])
|
|
||||||
|
|
||||||
return target.apply(thisArg, args_array)
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
var previousState = window.history.state;
|
|
||||||
setInterval(function() {
|
|
||||||
|
|
||||||
if (!window.location.pathname.startsWith(`${prefix}${btoa(url.origin)}/`)) {
|
|
||||||
|
|
||||||
history.replaceState('', '', `${prefix}${btoa(url.origin)}/${window.location.href.split('/').splice(3).join('/')}`);
|
|
||||||
}
|
|
||||||
}, 0.1);
|
|
|
@ -1,110 +0,0 @@
|
||||||
const WebSocket = require('ws');
|
|
||||||
|
|
||||||
// Setting Base64 encoding and decoding functions.
|
|
||||||
|
|
||||||
btoa = (str) => {
|
|
||||||
|
|
||||||
str = new Buffer.from(str).toString('base64');
|
|
||||||
|
|
||||||
return str;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
atob = (str) => {
|
|
||||||
|
|
||||||
str = new Buffer.from(str, 'base64').toString('utf-8');
|
|
||||||
|
|
||||||
return str;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = (server, config) => {
|
|
||||||
|
|
||||||
// Using the HTTP server as the WS server.
|
|
||||||
|
|
||||||
const wss = new WebSocket.Server({
|
|
||||||
server: server
|
|
||||||
});
|
|
||||||
|
|
||||||
wss.on('connection', (cli, req) => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
const svr = new WebSocket(atob(req.url.replace(config.prefix + 'ws/', '')));
|
|
||||||
|
|
||||||
svr.on('message', (data) => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
cli.send(data)
|
|
||||||
} catch (err) {}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Getting response from WS client to send to the user from the server.
|
|
||||||
|
|
||||||
svr.on('open', () => {
|
|
||||||
|
|
||||||
cli.on('message', (data) => {
|
|
||||||
|
|
||||||
svr.send(data)
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// Closes server when WS client closes.
|
|
||||||
|
|
||||||
cli.on('close', (code) => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
svr.close(code);
|
|
||||||
} catch (err) {
|
|
||||||
svr.close(1006)
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Closes client when WS server closes.
|
|
||||||
|
|
||||||
svr.on('close', (code) => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
cli.close(code);
|
|
||||||
} catch (err) {
|
|
||||||
cli.close(1006)
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Closes server when WS client errors.
|
|
||||||
|
|
||||||
cli.on('error', (err) => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
svr.close(1001);
|
|
||||||
} catch (err) {
|
|
||||||
svr.close(1006)
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Closes client when WS server errors.
|
|
||||||
|
|
||||||
svr.on('error', (err) => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
cli.close(1001);
|
|
||||||
} catch (err) {
|
|
||||||
cli.close(1006)
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
cli.close(1001);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
{
|
|
||||||
"_from": "alloyproxy@^1.1.0",
|
|
||||||
"_id": "alloyproxy@1.1.0",
|
|
||||||
"_inBundle": false,
|
|
||||||
"_integrity": "sha512-AlLoWex3qx2dWRO+3HovFjUWoRx4Lq9hEeyH5soIvJ0Y18VP2kgd8nuGirLJgJiVkoZyZJ31qzYK5q+vRsAebA==",
|
|
||||||
"_location": "/alloyproxy",
|
|
||||||
"_phantomChildren": {},
|
|
||||||
"_requested": {
|
|
||||||
"type": "range",
|
|
||||||
"registry": true,
|
|
||||||
"raw": "alloyproxy@^1.1.0",
|
|
||||||
"name": "alloyproxy",
|
|
||||||
"escapedName": "alloyproxy",
|
|
||||||
"rawSpec": "^1.1.0",
|
|
||||||
"saveSpec": null,
|
|
||||||
"fetchSpec": "^1.1.0"
|
|
||||||
},
|
|
||||||
"_requiredBy": [
|
|
||||||
"#USER",
|
|
||||||
"/"
|
|
||||||
],
|
|
||||||
"_resolved": "https://registry.npmjs.org/alloyproxy/-/alloyproxy-1.1.0.tgz",
|
|
||||||
"_shasum": "95d4064bd691a0f949e1a66de9bd966e1c0fff7f",
|
|
||||||
"_spec": "alloyproxy@^1.1.0",
|
|
||||||
"_where": "C:\\Users\\Not A Porxy\\Documents\\HolyUnblockerWorkspace\\HolyUB",
|
|
||||||
"author": {
|
|
||||||
"name": "Titanium Network"
|
|
||||||
},
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/titaniumnetwork-dev/alloyproxy/issues"
|
|
||||||
},
|
|
||||||
"bundleDependencies": false,
|
|
||||||
"dependencies": {
|
|
||||||
"ws": "^7.4.0"
|
|
||||||
},
|
|
||||||
"deprecated": false,
|
|
||||||
"description": "Proxy library to unblock the web!",
|
|
||||||
"homepage": "https://github.com/titaniumnetwork-dev/alloyproxy#readme",
|
|
||||||
"keywords": [
|
|
||||||
"proxy",
|
|
||||||
"unblocker",
|
|
||||||
"web",
|
|
||||||
"proxy"
|
|
||||||
],
|
|
||||||
"license": "ISC",
|
|
||||||
"main": "index.js",
|
|
||||||
"name": "alloyproxy",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/titaniumnetwork-dev/alloyproxy.git"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
|
||||||
},
|
|
||||||
"version": "1.1.0"
|
|
||||||
}
|
|
|
@ -24,14 +24,14 @@ function goToUrl(url, stealth, nolag) {
|
||||||
* goProx.proxy(url-string, stealth-boolean-optional)
|
* goProx.proxy(url-string, stealth-boolean-optional)
|
||||||
*
|
*
|
||||||
* Examples:
|
* Examples:
|
||||||
* goProx.alloy("https://google.com")
|
* goProx.corrosion("https://google.com")
|
||||||
* goProx.womginx("discord.com", true)
|
* goProx.womginx("discord.com", true)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
goProx = {
|
goProx = {
|
||||||
alloy: function(url, stealth) {
|
corrosion: function(url, stealth) {
|
||||||
document.cookie = 'oldsmobile=badcar; expires=' + (Date.now() + 259200) + '; SameSite=Lax; domain=.' + getDomain() + '; path=/; Secure;';
|
document.cookie = 'oldsmobile=badcar; expires=' + (Date.now() + 259200) + '; SameSite=Lax; domain=.' + getDomain() + '; path=/; Secure;';
|
||||||
goToUrl("https://" + getDomain() + "/fetch/" + btoa(url.substring(0, 4) == "http" ? url : "https://" + url), stealth);
|
goToUrl("https://" + getDomain() + "/fetch/" + url, stealth);
|
||||||
},
|
},
|
||||||
womginx: function(url, stealth) {
|
womginx: function(url, stealth) {
|
||||||
document.cookie = 'wgauth=yes; expires=' + (Date.now() + 259200) + '; SameSite=None; domain=.' + getDomain() + '; path=/; Secure;';
|
document.cookie = 'wgauth=yes; expires=' + (Date.now() + 259200) + '; SameSite=None; domain=.' + getDomain() + '; path=/; Secure;';
|
||||||
|
@ -79,4 +79,4 @@ goProx = {
|
||||||
function goToChatbox(stealth) {
|
function goToChatbox(stealth) {
|
||||||
document.cookie = 'oldsmobile=badcar; expires=' + (Date.now() + 259200) + '; SameSite=Lax; domain=.' + getDomain() + '; path=/; Secure;';
|
document.cookie = 'oldsmobile=badcar; expires=' + (Date.now() + 259200) + '; SameSite=Lax; domain=.' + getDomain() + '; path=/; Secure;';
|
||||||
goToUrl("https://c." + getDomain() + "/app", stealth);
|
goToUrl("https://c." + getDomain() + "/app", stealth);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,14 @@ try {
|
||||||
console.log("No url box: " + e);
|
console.log("No url box: " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alloy
|
// Corrosion
|
||||||
tryGetElement('al').onclick = function(e) {
|
tryGetElement('al').onclick = function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (url.value) goProx.alloy(url.value, true);
|
if (url.value) goProx.corrosion(url.value, true);
|
||||||
}
|
}
|
||||||
tryGetElement('albp').onclick = function(e) {
|
tryGetElement('albp').onclick = function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (url.value) goProx.alloy(url.value);
|
if (url.value) goProx.corrosion(url.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Womginx
|
// Womginx
|
||||||
|
@ -111,4 +111,4 @@ tryGetElement('ytbtn').onclick = function(e) {
|
||||||
tryGetElement('ytbp').onclick = function(e) {
|
tryGetElement('ytbp').onclick = function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// goProx.pydodge("https://youtube.com");
|
// goProx.pydodge("https://youtube.com");
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,7 @@
|
||||||
employed by insti<wbr>tution<wbr>s like scho<wbr>ols or workpl<wbr>aces.</p>
|
employed by insti<wbr>tution<wbr>s like scho<wbr>ols or workpl<wbr>aces.</p>
|
||||||
<p><br> Qu<wbr>ite A Fa<wbr>ncy Emer<wbr>ald (Cre<wbr>ator <wbr>and Ow<wbr>ner, Disc<wbr>ord: Qui<wbr>te A Fa<wbr>ncy Emer<wbr>ald#00<wbr>01)
|
<p><br> Qu<wbr>ite A Fa<wbr>ncy Emer<wbr>ald (Cre<wbr>ator <wbr>and Ow<wbr>ner, Disc<wbr>ord: Qui<wbr>te A Fa<wbr>ncy Emer<wbr>ald#00<wbr>01)
|
||||||
<br><strong>− Ol<wbr>yB (Contributor, T<wbr>ab Cl<wbr>oak, Emula<wbr>tors, D­iscord­: O<wbr>lyB#94<wbr>20)</strong>
|
<br><strong>− Ol<wbr>yB (Contributor, T<wbr>ab Cl<wbr>oak, Emula<wbr>tors, D­iscord­: O<wbr>lyB#94<wbr>20)</strong>
|
||||||
|
<br><strong>- Lin<wbr>uxTerm (Contributor, proxy and web developer)</strong>
|
||||||
<br>Be sure to join the T­itan­iu­m Netwo­rk Dis­co­rd <a id="tnlink">here</a>!
|
<br>Be sure to join the T­itan­iu­m Netwo­rk Dis­co­rd <a id="tnlink">here</a>!
|
||||||
<br><strong>−−</strong>
|
<br><strong>−−</strong>
|
||||||
<br>Contributors and Notable Mentions:
|
<br>Contributors and Notable Mentions:
|
||||||
|
@ -165,4 +166,4 @@
|
||||||
<script src="assets/js/bs-init.js"></script>
|
<script src="assets/js/bs-init.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,157 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
|
||||||
<title>H​oly Unb​loc​ke​r</title>
|
|
||||||
<meta name="description" content="G​et p​ast in​te​r​net ce​n​s​or​sh​ip tod​a​y! :D">
|
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/img/icon.png">
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://unpkg.com">
|
|
||||||
<link rel="dns-prefetch" href="https://unpkg.com">
|
|
||||||
<link rel="preconnect" href="https://arc.io">
|
|
||||||
<link rel="dns-prefetch" href="https://arc.io">
|
|
||||||
<link rel="stylesheet" href="assets/css/styles.min.css">
|
|
||||||
<link rel="stylesheet" href="https://unpkg.com/ionicons@4.5.10-0/dist/css/ionicons.min.css">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat+Alternates">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web:400,600,700">
|
|
||||||
<script defer="defer" src="assets/js/header.js"></script>
|
|
||||||
<script async src="https://arc.io/widget.min.js#2BzvQ1em"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
|
||||||
<div>
|
|
||||||
<div class="header-dark">
|
|
||||||
<nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;">
|
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
|
||||||
<div class="container"><a class="navbar-brand" data-bs-hover-animate="pulse" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">H­o­ly U­n­b­lo­c­k­er</a>
|
|
||||||
<button data-toggle="collapse" class="navbar-toggler" data-target="#navcol-1">
|
|
||||||
<span class="sr-only">T­ogg­le nav­igati­on</span><span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
<div class="collapse navbar-collapse" id="navcol-1">
|
|
||||||
<ul class="nav navbar-nav ml-auto">
|
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
|
||||||
<li class="nav-item" data-bs-hover-animate="pulse"><a class="nav-link" href="/?z" style="font-family: 'Montserrat Alternates', sans-serif;">W­eb Pr­ox­ie­s</a></li>
|
|
||||||
<li class="nav-item" data-bs-hover-animate="pulse"><a class="nav-link" href="/?g" style="font-family: 'Montserrat Alternates', sans-serif;">G­a­me­s</a></li>
|
|
||||||
<li class="nav-item" data-bs-hover-animate="pulse"><a class="nav-link" href="/?y" style="font-family: 'Montserrat Alternates', sans-serif;">Yo­uT­u­be</a></li>
|
|
||||||
<li class="nav-item" data-bs-hover-animate="pulse"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D­isc­or­d</a></li>
|
|
||||||
<li class="nav-item" id="ch" data-bs-hover-animate="pulse"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Ch­a­tbo­x</a></li>
|
|
||||||
<li class="nav-item dropdown">
|
|
||||||
<a class="dropdown-toggle nav-link" data-bs-hover-animate="pulse" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: #fff;font-family: 'Montserrat Alternates', sans-serif;">M­or­e</a>
|
|
||||||
<div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;">
|
|
||||||
<a class="dropdown-item text-left text-white-50" role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">D­oc­s</a>
|
|
||||||
<a class="dropdown-item text-left text-white-50" role="presentation" href="/?faq" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">FA­Q</a>
|
|
||||||
<a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre­d­its</a>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
|
||||||
<li class="nav-item dropdown">
|
|
||||||
<a class="dropdown-mod nav-link" style="font-size: 16px" data-animate="pulse" data-toggle="dropdown" aria-expanded="false" href="#">
|
|
||||||
<i class="ion-md-options"></i>
|
|
||||||
</a>
|
|
||||||
<div id="csel" class="dropdown-menu" role="menu">
|
|
||||||
<p class="csel-l">T­ab Cl­oak</p>
|
|
||||||
<p class="csel-p">Ch­a­nge t­he Tit­le.</p>
|
|
||||||
<form id="titleform"><input class="bg-dark border rounded-0 border shadow-lg" type="text" placeholder="Tab Title"><input class="btn btn-dark btn-sm bg-dark border-dark rounded-1 shadow-lg" style="margin-top: 5px;" data-bs-hover-animate="pulse" type="submit" value="Ap­ply"></form>
|
|
||||||
<p class="csel-p" style="margin-top: 5px;">C­han­ge t­he <a href="/?i">Ic­on</a>.</p>
|
|
||||||
<form id="iconform"><input class="bg-dark border rounded-0 border shadow-lg" type="url" placeholder="Icon URL"><input class="btn btn-dark btn-sm bg-dark border-dark rounded-1 shadow-lg" style="margin-top: 5px;" data-bs-hover-animate="pulse" type="submit" value="Ap­ply"></form>
|
|
||||||
<form id="toolsform" style="margin-top: 10px;"><a class="btn btn-dark btn-lg bg-dark border-dark rounded-1 border shadow-lg" data-bs-hover-animate="pulse" href="/?x" type="button" class="tb-btn">Book­mar­kl­et­s</a></form>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
|
||||||
<div id="particles-js" class="in-bg">
|
|
||||||
<div class="d-flex justify-content-center" style="position:absolute;width:100%;">
|
|
||||||
<script src="particles.js"></script>
|
|
||||||
<script>
|
|
||||||
/* particlesJS.load(@dom-id, @path-json, @callback (optional)); */
|
|
||||||
particlesJS.load('particles-js', 'particles.json', function() {
|
|
||||||
console.log('particlesjs loaded.......');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<div class="d-flex justify-content-center">
|
|
||||||
<div class="container-fluid border rounded text-center justify-content-center align-items-center button" style="color: rgb(255,255,255);filter: blur(0px); opacity: 0.95; padding-left: 50px; padding-right: 50px;margin:0px;">
|
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
|
||||||
<form>
|
|
||||||
<p class="s-text-header" style="font-size: 46px;">Al<wbr>loy Pro<wbr>xy</p>
|
|
||||||
<p class="s-text-p1" style="font-family: 'Montserrat Alternates', sans-serif;">A fast, lightweight pr<wbr>oxy developed by Tita<wbr>nium N<wbr>etwork.</p>
|
|
||||||
<div id="scontainerb" class="input-group">
|
|
||||||
<div class="input-group-prepend"></div><input id="url" class="form-control form-control-lg hb-border-color shadow-sm" type="text" name="url" inputmode="url" autocomplete="off" style="width: 230px;border-radius: 0.25rem;font-family: 'Montserrat Alternates', sans-serif;opacity: 0.80; height: 47px; color:rgb(255,255,255);"
|
|
||||||
placeholder="ht­tps­://b­i­­ng.c­om">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button id="albp" class="glow-on-hover btn-dark btn-lg text-hb hb-border-color shadow-sm" data-bs-hover-animate="pulse" name="button" type="submit" style="width: 85px;padding: 2px;margin-left: 5px;height: 47px;font-family: 'Montserrat Alternates', sans-serif;font-size: 16px;">Classic</button>
|
|
||||||
<button id="al" class="glow-on-hover btn-dark text-center btn-lg text-hb hb-border-color shadow-sm" data-bs-hover-animate="pulse" name="button" type="submit" style="width: 85px;padding: 2px;margin-left: 4px;height: 47px;font-family: 'Montserrat Alternates', sans-serif;font-size: 16px;">Stealth</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="text-white" style="font-size: 20px; padding-top: 5px; font-family: 'Montserrat Alternates', sans-serif;">
|
|
||||||
More Inf<wbr>ormation:<br></p>
|
|
||||||
<p class="text-hb s-text-p2" style="font-family: Lato, sans-serif;">
|
|
||||||
Wo<wbr>rks with Di<wbr>scord, Re<wbr>ddi<wbr>t, Twi<wbr>tte<wbr>r and Yout<wbr>ube.
|
|
||||||
<br>The recommended p<wbr>ro<wbr>xy for most sites with amazing support.
|
|
||||||
<br><br>Co<wbr>mmo<wbr>n Err<wbr>o<wbr>rs wi<wbr>th So<wbr>luti<wbr>ons:
|
|
||||||
<br>- For Yo<wbr>uTu<wbr>be support be sure to use the URL of the video you want to watch. (Cannot GET /watch error)
|
|
||||||
<br>- Try using Clas<wbr>sic mode or doing 'Reload Frame'. ("cdn.example.com" cannot be reached.)
|
|
||||||
<br>- You cannot log
|
|
||||||
<wbr>in normally into Dis<wbr>co<wbr>rd. Q<wbr>R lo<wbr>gin only. Read the Di<wbr>sc<wbr>o<wbr>rd page for solutions. (Site Key Error)
|
|
||||||
<p class="text-hb s-text-p2" style="font-family: Lato, sans-serif;">Git<wbr>Hub: <a class="text-hb" id="allink"><strong> https://github​.com/ti​taniumnetwork-​dev/alloypro​xy</strong></a>
|
|
||||||
</p>
|
|
||||||
</form>
|
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
|
||||||
<div class="footer-dark ft-bg">
|
|
||||||
<footer>
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6 item text">
|
|
||||||
<h3><a href="/">Ho<wbr>ly Unb<wbr>lo<wbr>c<wbr>ker</a></h3>
|
|
||||||
<p>Ma<wbr>de by St<wbr>ud<wbr>en<wbr>ts, Fo<wbr>r Stu<wbr>den<wbr>ts. </p>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-md-3 item">
|
|
||||||
<h3>Se<wbr>rvic<wbr>es</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a id="allink">Al<wbr>loy</a></li>
|
|
||||||
<li><a id="plink">PM P<wbr>ro<wbr>xy</a></li>
|
|
||||||
<li><a id="nclink">No<wbr>d<wbr>eClu<wbr>st<wbr>e<wbr>rs</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-md-3 item">
|
|
||||||
<h3>About</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a id="hblink">G<wbr>itHub</a></li>
|
|
||||||
<li><a href="/?t">P<wbr>riva<wbr>cy and Te<wbr>rms of Ser<wbr>v<wbr>ice</a></li>
|
|
||||||
<li><a href="/?c">Cre<wbr>dit<wbr>s</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="col item social center ft-g">
|
|
||||||
<a id="hblink2">
|
|
||||||
<i class="ion-logo-github"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="copyright">H<wbr>ol<wbr>y U<wbr>nb<wbr>lo<wbr>cke<wbr>r © 20<wbr>21</p>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
|
||||||
<script src="expr/common.js"></script>
|
|
||||||
<script src="assets/js/links.js"></script>
|
|
||||||
<script src="expr/surf.js"></script>
|
|
||||||
<script defer="defer" src="assets/js/jquery.min.js"></script>
|
|
||||||
<script defer="defer" src="assets/bootstrap/js/bootstrap.min.js"></script>
|
|
||||||
<script src="assets/js/bs-init.js"></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -92,7 +92,7 @@
|
||||||
</div>
|
</div>
|
||||||
<p class="text-white" style="font-size: 20px; padding-top: 5px; font-family: 'Montserrat Alternates', sans-serif;">
|
<p class="text-white" style="font-size: 20px; padding-top: 5px; font-family: 'Montserrat Alternates', sans-serif;">
|
||||||
More Inf<wbr>ormation:<br></p>
|
More Inf<wbr>ormation:<br></p>
|
||||||
<p class="text-hb s-text-p2" style="font-family: Lato, sans-serif;">Wo<wbr>rks with YouT<wbr>ube (Full Support), Di<wbr>scord, Re<wbr>ddi<wbr>t and Twi<wbr>tte<wbr>r.
|
<p class="text-hb s-text-p2" style="font-family: Lato, sans-serif;">Wo<wbr>rks with YouT<wbr>ube, Di<wbr>scord, Re<wbr>ddi<wbr>t and Twi<wbr>tte<wbr>r.
|
||||||
<br>Corr​osi​on is curre​ntly the m​ost reco​mmen​ded pro​xy with​ a hi​gh libr​ary of support​ed si​tes.
|
<br>Corr​osi​on is curre​ntly the m​ost reco​mmen​ded pro​xy with​ a hi​gh libr​ary of support​ed si​tes.
|
||||||
<br><br>Co<wbr>mmo<wbr>n Err<wbr>o<wbr>rs wi<wbr>th So<wbr>luti<wbr>ons:
|
<br><br>Co<wbr>mmo<wbr>n Err<wbr>o<wbr>rs wi<wbr>th So<wbr>luti<wbr>ons:
|
||||||
<br>- Try using Clas<wbr>sic mode or doing 'Reload Frame'. ("cdn.example.com" cannot be reached.)
|
<br>- Try using Clas<wbr>sic mode or doing 'Reload Frame'. ("cdn.example.com" cannot be reached.)
|
||||||
|
@ -151,4 +151,4 @@
|
||||||
<script src="assets/js/bs-init.js"></script>
|
<script src="assets/js/bs-init.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -85,14 +85,12 @@
|
||||||
<p class="s-text-p1" style="font-family: 'Montserrat Alternates', sans-serif;">Choo­se which pr<wbr>ox­y you would like to use. Belo­w is s­ome info­rma­ti­on.</p>
|
<p class="s-text-p1" style="font-family: 'Montserrat Alternates', sans-serif;">Choo­se which pr<wbr>ox­y you would like to use. Belo­w is s­ome info­rma­ti­on.</p>
|
||||||
<div style="margin: 2%;padding: 5px;">
|
<div style="margin: 2%;padding: 5px;">
|
||||||
<a class="btn btn-group text-hb hb-button glow-on-hover" role="button" data-bs-hover-animate="pulse" href="/?q">Co<wbr>rro<wbr>si<wbr>on</a>
|
<a class="btn btn-group text-hb hb-button glow-on-hover" role="button" data-bs-hover-animate="pulse" href="/?q">Co<wbr>rro<wbr>si<wbr>on</a>
|
||||||
<a class="btn btn-group text-hb hb-button glow-on-hover" role="button" data-bs-hover-animate="pulse" href="/?a">Al<wbr>loy P<wbr>ro<wbr>xy</a>
|
|
||||||
<a class="btn btn-group text-hb hb-button glow-on-hover" role="button" data-bs-hover-animate="pulse" href="/?w">W<wbr>om<wbr>gi<wbr>nx</a>
|
<a class="btn btn-group text-hb hb-button glow-on-hover" role="button" data-bs-hover-animate="pulse" href="/?w">W<wbr>om<wbr>gi<wbr>nx</a>
|
||||||
<a class="btn btn-group text-hb hb-button glow-on-hover" role="button" data-bs-hover-animate="pulse" href="/?p">Sy<wbr>sY<wbr>A Pr<wbr>o<wbr>xy</a>
|
<a class="btn btn-group text-hb hb-button glow-on-hover" role="button" data-bs-hover-animate="pulse" href="/?p">Sy<wbr>sY<wbr>A Pr<wbr>o<wbr>xy</a>
|
||||||
<a class="btn btn-group text-hb hb-button glow-on-hover" role="button" data-bs-hover-animate="pulse" href="/?e">V<wbr>ia Un<wbr>b<wbr>loc<wbr>ker</a>
|
<a class="btn btn-group text-hb hb-button glow-on-hover" role="button" data-bs-hover-animate="pulse" href="/?e">V<wbr>ia Un<wbr>b<wbr>loc<wbr>ker</a>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-white" style="font-size: 16px;font-family: Lato, sans-serif;">More Information:<br></p>
|
<p class="text-white" style="font-size: 16px;font-family: Lato, sans-serif;">More Information:<br></p>
|
||||||
<p class="text-hb-light s-text-p2" style="font-family: Lato, sans-serif;">Cor​rosion: Of​fici​al pro​xy o​f Ti​tan​ium Ne​two​rk wi​th en​hanc​ed suppo​rt for a lar​ge major​ity o​f si​tes and hCA​PTCH​A.
|
<p class="text-hb-light s-text-p2" style="font-family: Lato, sans-serif;">Cor​rosion: Of​fici​al pro​xy o​f Ti​tan​ium Ne​two​rk wi​th en​hanc​ed suppo​rt for a lar​ge major​ity o​f si​tes and hCA​PTCH​A. (Recommended)
|
||||||
<br>A<wbr>llo<wbr>y: Sup<wbr>port<wbr>s a la<wbr>rge majo<wbr>rity of sit<wbr>es with par​tial su​pport for Yo​uTub​e or Dis​ord. Corro​sion i​s it​s succ​essor.
|
|
||||||
<br>Wo<wbr>mgi­<wbr>nx: Useful for sites which use reC<wbr>APTC<wbr>HA.
|
<br>Wo<wbr>mgi­<wbr>nx: Useful for sites which use reC<wbr>APTC<wbr>HA.
|
||||||
<br>S<wbr>ysY<wbr>A: Sup<wbr>port<wbr>ive for mo<wbr>st si<wbr>tes whi<wbr>le ens­uri<wbr>ng priva<wbr>cy.
|
<br>S<wbr>ysY<wbr>A: Sup<wbr>port<wbr>ive for mo<wbr>st si<wbr>tes whi<wbr>le ens­uri<wbr>ng priva<wbr>cy.
|
||||||
<br>Vi<wbr>a: Fa<wbr>st pro<wbr>xy which suppo<wbr>rts many ga<wbr>me si<wbr>tes and g<wbr>rea<wbr>t for do<wbr>wn<wbr>loa<wbr>ds.
|
<br>Vi<wbr>a: Fa<wbr>st pro<wbr>xy which suppo<wbr>rts many ga<wbr>me si<wbr>tes and g<wbr>rea<wbr>t for do<wbr>wn<wbr>loa<wbr>ds.
|
||||||
|
@ -152,4 +150,4 @@
|
||||||
<script src="assets/js/bs-init.js"></script>
|
<script src="assets/js/bs-init.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue