This project has been archived because I no longer want to develop proxies. There are too many aspects to cover and too frequent rewrites. Use an alternative such as https://github.com/titaniumnetwork-dev/alloy .
git clone https://github.com/sysce/proxy ./sys-proxy
node ./sys-proxy/demo
npm i sys-proxy
- krunker.io
- 1v1.lol
- justbuild.lol
- youtube.com ( only player )
- twitch.tv
See the demo folder for more usage examples
var nodehttp = require('sys-nodehttp'),
rewriter = require('sys-proxy'),
server = new nodehttp.server({
port: 7080,
static: path.join(__dirname, 'public'),
}),
rw = new rewriter({
prefix: '/service',
codec: rewriter.codec.xor,
server: server,
title: 'Service',
});
// [0000] server listening on http://localhost:7080/
- index
Rewriter
configObjectconfig.adblockBoolean? Determines if the easylist.txt file should be used for checking URLs, this may decrease performance and increase resource usageconfig.wsBoolean? Determines if websocket support should be addedconfig.codecObject? The codec to be used (rewriter.codec.plain, base64, xor)config.prefixBoolean? The prefix to run the proxy onconfig.interfaceBoolean? The network interface to request fromconfig.timeoutBoolean? The maximum request timeout timeconfig.titleBoolean? The title of the pages visitedconfig.http_agentObject? Agent to be used for http: / ws: requestsconfig.https_agentObject? Agent to be used for https: / wss: requests
serverObject nodehttp/express server to run the proxy on, only on the serverside this is required
mimeObject Contains mime data for categorizing mimesattrObject Contains attribute data for categorizing attributes and tagsattr_entObject Object.entries called on attr propertyregexObject Contains regexes used throughout the rewriterconfigObject Where the config argument is storedURLObject class extending URL with thefullpathproperty
Prefixes a URL and encodes it
valuedataObject Standard object for all rewriter handlers (optional, default{})data.originObject The page location or URL (eg localhost)data.baseObject? Base URL, default is decoded version of the origindata.routeObject? Adds to the query params if the result should be handled by the rewriterdata.typeObject? The type of URL this is (eg js, css, html), helps the rewriter determine how to handle the responsedata.wsObject? If the URL is a WebSocket
null-null(String | URL | Request) URL value
Returns String Proxied URL
Attempts to decode a URL previously ran throw the URL handler
valuedata(optional, default{})null-nullString URL value
Returns String Normal URL
Scopes JS and adds in filler objects
Returns String
Rewrites CSS urls and selectors
Returns String
Undos CSS rewriting
Returns String
Rewrites manifest JSON data, needs the data object since the URL handler is called
valueString Manifest codedataObject Standard object for all rewriter handlers (optional, default{})
Returns String
Parses and modifies HTML, needs the data object since the URL handler is called
valueString Manifest codedataObject Standard object for all rewriter handlers (optional, default{})data.snippetBoolean? If the HTML code is a snippet and if it shouldn't have the rewriter scripts addeddata.originObject The page location or URL (eg localhost)data.baseObject? Base URL, default is decoded version of the origindata.routeObject? Adds to the query params if the result should be handled by the rewriter
Returns String
Validates and parses attributes, needs data since multiple handlers are called
node(Node | Object) Object containing at least getAttribute and setAttributenameString Name of the attributedataObject Standard object for all rewriter handlers
Soon to add removing the servers IP, mainly for converting values to strings when handling
value(String | Buffer) Data to convert to a stringdataObject Standard object for all rewriter handlers
Decoding blobs
dataBlob
Returns String
Determines the attribute type using the attr_ent property
Returns String
Prepares headers to be sent to the client from a server
valuedata(optional, default{})null-nullObject Headers
Returns Object
Prepares headers to be sent to the server from a client, calls URL handler so data object is needed
valuedataObject Standard object for all rewriter handlers (optional, default{})data.originObject The page location or URL (eg localhost)data.baseObject? Base URL, default is decoded version of the origindata.routeObject? Adds to the query params if the result should be handled by the rewriterdata.typeObject? The type of URL this is (eg js, css, html), helps the rewriter determine how to handle the responsedata.wsObject? If the URL is a WebSocket
null-nullObject Headers
Returns Object
Prepares cookies to be sent to the client from a server, calls URL handler so
valueString Cookie headerdataObject Standard object for all rewriter handlers (optional, default{})
Returns Object
Prepares cookies to be sent to the server from a client, calls URL handler so
valueString Cookie headerdataObject Standard object for all rewriter handlers (optional, default{})
Returns Object
Decode params of URL, takes the prefix and then decodes a querystring
Returns URLSearchParams
Decompresses response data
Validates a URL
Returns (Undefined | URL) Result, is undefined if an error occured
Returns a string version of the config`
Returns Object
Retrieves global data/creates if needed
Returns Object
Globals, called in the client to set any global data or get the proper fills object
urlURLURL] - needed if page URL is not set globally
Serializes a JSDOM or DOMParser object
domDOMDocument
Returns String
Wraps a string
strString
Returns String
Runs a checksum on a string
re(optional, default5381)t(optional, defaultr.length)String
Returns Number
Recieve request => parse URL => send request to server => rewrite content => send to client
To achieve accuracy when rewriting, this proxy uses "scoping". All js is wrapped in a closure to override variables that otherwise are not possible normally (window, document)
Proxies are used to change or extend any value to be in line with rewriting URLs
Any occurance of this is changed to call the global rw_this function with the this value, if the this value has a property indicating that the value has a proxied version, return the proxied version.
An example:
Call the rewriter and parse:
if(window.location == this.location)alert('Everything checks out!');
Expected result:
{let fills=<bundled code>,window=fills.this,document=fills.document;if(window.location == rw_this(this).location)alert('Everything checks out!');
//# sourceURL=anonymous:1
}
this in the input code is defined as window, the window has a proxied version that will also determine if any properties are proxied and give a result.
this => fills.this
this.location => fills.url
A part of getting down full HTML rewriting is also making sure any dynamically made elements are rewritten.
Getters and setters are used for properties on the Node.prototype object for such as but not limited to:
outerHTMLinnerHTMLgetAttributesetAttributesetAttributeNSinsertAdjacentHTMLnonceintegrity
- every attribute that is rewritten in the HTML side of things
Any property/function that inserts raw html code that is not rewritten is ran through the rewriters HTML handler. Properties are handled by the rewriters HTML property handler (for consistency)
A basic regex to locate all url() blocks is used and the rewriters URL handler is called with the value and meta for the page
A bundled version of JSDOM is used to achieve accuracy and consistency when rewriting and DOMParser in the browser.
Each property is iterated and in the rewriter a huge array containing information for determining the type of attribute being worked with is used ( this includes tag and name).
- If the type is a URL then the resulting value is determined by the rewriters URL handler
- If the type is JS then the resulting value is determined by the rewriters JS handler along with being wrapped for encoding
- If the type is CSS then the resulting value is determined by the rewriters CSS handler along
A basic JSON.stringify checking if the key is src or key or start_url and if it is then the rewriters URL handler is used to determine the result.