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
config
Objectconfig.adblock
Boolean? Determines if the easylist.txt file should be used for checking URLs, this may decrease performance and increase resource usageconfig.ws
Boolean? Determines if websocket support should be addedconfig.codec
Object? The codec to be used (rewriter.codec.plain, base64, xor)config.prefix
Boolean? The prefix to run the proxy onconfig.interface
Boolean? The network interface to request fromconfig.timeout
Boolean? The maximum request timeout timeconfig.title
Boolean? The title of the pages visitedconfig.http_agent
Object? Agent to be used for http: / ws: requestsconfig.https_agent
Object? Agent to be used for https: / wss: requests
server
Object nodehttp/express server to run the proxy on, only on the serverside this is required
mime
Object Contains mime data for categorizing mimesattr
Object Contains attribute data for categorizing attributes and tagsattr_ent
Object Object.entries called on attr propertyregex
Object Contains regexes used throughout the rewriterconfig
Object Where the config argument is storedURL
Object class extending URL with thefullpath
property
Prefixes a URL and encodes it
value
data
Object Standard object for all rewriter handlers (optional, default{}
)data.origin
Object The page location or URL (eg localhost)data.base
Object? Base URL, default is decoded version of the origindata.route
Object? Adds to the query params if the result should be handled by the rewriterdata.type
Object? The type of URL this is (eg js, css, html), helps the rewriter determine how to handle the responsedata.ws
Object? 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
value
data
(optional, default{}
)null-null
String 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
value
String Manifest codedata
Object Standard object for all rewriter handlers (optional, default{}
)
Returns String
Parses and modifies HTML, needs the data object since the URL handler is called
value
String Manifest codedata
Object Standard object for all rewriter handlers (optional, default{}
)data.snippet
Boolean? If the HTML code is a snippet and if it shouldn't have the rewriter scripts addeddata.origin
Object The page location or URL (eg localhost)data.base
Object? Base URL, default is decoded version of the origindata.route
Object? 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 setAttributename
String Name of the attributedata
Object 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 stringdata
Object Standard object for all rewriter handlers
Decoding blobs
data
Blob
Returns String
Determines the attribute type using the attr_ent
property
Returns String
Prepares headers to be sent to the client from a server
value
data
(optional, default{}
)null-null
Object Headers
Returns Object
Prepares headers to be sent to the server from a client, calls URL handler so data object is needed
value
data
Object Standard object for all rewriter handlers (optional, default{}
)data.origin
Object The page location or URL (eg localhost)data.base
Object? Base URL, default is decoded version of the origindata.route
Object? Adds to the query params if the result should be handled by the rewriterdata.type
Object? The type of URL this is (eg js, css, html), helps the rewriter determine how to handle the responsedata.ws
Object? If the URL is a WebSocket
null-null
Object Headers
Returns Object
Prepares cookies to be sent to the client from a server, calls URL handler so
value
String Cookie headerdata
Object 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
value
String Cookie headerdata
Object 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
url
URL
URL] - needed if page URL is not set globally
Serializes a JSDOM or DOMParser object
dom
DOM
Document
Returns String
Wraps a string
str
String
Returns String
Runs a checksum on a string
r
e
(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:
outerHTML
innerHTML
getAttribute
setAttribute
setAttributeNS
insertAdjacentHTML
nonce
integrity
- 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.