Skip to content

Commit

Permalink
v1.1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
binary-person committed Mar 22, 2022
1 parent 51209b3 commit 1d2bcca
Show file tree
Hide file tree
Showing 16 changed files with 119 additions and 26 deletions.
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
src/client/*.min.*
src/client/*.min.*
src/client/hammerhead.js
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ node_modules/

# don't commit generated builds or env files
src/client/*.min.*
src/client/hammerhead.js
.env

# don't commit session data
Expand Down
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
src/client/*.min.*
src/client/*.min.*
src/client/hammerhead.js
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## v1.1.2

- build to rammerhead.js and rammerhead.min.js
- fix same-domain iframes
- add jsdoc definitions for rammerhead store classes
- fix http proxy setting not deleting correctly

## v1.1.1

- fix uncatchable connection crash errors
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rammerhead",
"version": "1.1.1",
"version": "1.1.2",
"description": "User friendly web proxy powered by testcafe-hammerhead",
"main": "src/index.js",
"scripts": {
Expand Down
15 changes: 9 additions & 6 deletions src/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,24 @@ const UglifyJS = require('uglify-js');

// modify unmodifable items that cannot be hooked in rammerhead.js
fs.writeFileSync(
path.join(__dirname, './client/hammerhead.min.js'),
path.join(__dirname, './client/hammerhead.js'),
fs
.readFileSync(path.join(__dirname, '../node_modules/testcafe-hammerhead/lib/client/hammerhead.js'), 'utf8')
.replace(
'function parseProxyUrl$1',
'window.overrideParseProxyUrl = function(func) {parseProxyUrl$$1 = func}; $&'
)
.replace('isCrossDomainParent = parentLocationWrapper === parentWindow.location', 'isCrossDomainParent = parentLocationWrapper === parentWindow.location || !parentWindow["%hammerhead%"]')
.replace('function isCrossDomainWindows', 'window.overrideIsCrossDomainWindows = function(func) {isCrossDomainWindows = func}; $&')
.replace('function getProxyUrl$1', 'window.overrideGetProxyUrl = function(func) {getProxyUrl$$1 = func}; $&')
.replace('return window.location.search;', 'return (new URL(get$$2())).search;')
.replace('return window.location.hash;', 'return (new URL(get$$2())).hash;')
.replace('setter: function (search) {', '$& var url = new URL(get$$2()); url.search = search; window.location = convertToProxyUrl(url.href); return search;')
.replace('setter: function (hash) {', '$& var url = new URL(get$$2()); url.hash = hash; window.location.hash = (new URL(convertToProxyUrl(url.href))).hash; return hash;')
);

fs.writeFileSync(path.join(__dirname, './client/rammerhead.min.js'), fs.readFileSync(path.join(__dirname, './client/rammerhead.js')));

const copy = (oldPath, newPath) => fs.cpSync(path.join(__dirname, oldPath), path.join(__dirname, newPath));
const minify = fileName => {
const filePath = path.join(__dirname, './client', fileName);
const minified = UglifyJS.minify(fs.readFileSync(filePath, 'utf8'));
Expand All @@ -31,7 +33,8 @@ const minify = fileName => {
fs.writeFileSync(filePath, minified.code, 'utf8');
};

if (!process.env.DEVELOPMENT) {
minify('rammerhead.min.js');
minify('hammerhead.min.js');
}
copy('./client/rammerhead.js', './client/rammerhead.min.js');
copy('./client/hammerhead.js', './client/hammerhead.min.js');

minify('rammerhead.min.js');
minify('hammerhead.min.js');
30 changes: 27 additions & 3 deletions src/classes/RammerheadMemoryStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,26 @@ class RammerheadSessionMemoryStore extends RammerheadSessionAbstractStore {
setInterval(() => this._cleanupRun(staleTimeout, maxToLive), cleanupInterval).unref();
}

/**
* @returns {string[]} - list of session ids in store
*/
keys() {
return Array.from(this.mapStore.keys());
}
/**
* @param {string} id
* @returns {boolean}
*/
has(id) {
const exists = this.mapStore.has(id);
this.logger.debug(`(MemoryStore.has) ${id} ${exists}`);
return exists;
}
/**
* @param {string} id
* @param {boolean} updateActiveTimestamp
* @returns {RammerheadSession|undefined}
*/
get(id, updateActiveTimestamp = true) {
if (!this.has(id)) return;
this.logger.debug(`(MemoryStore.get) ${id} ${updateActiveTimestamp}`);
Expand All @@ -39,23 +51,35 @@ class RammerheadSessionMemoryStore extends RammerheadSessionAbstractStore {

return session;
}
/**
* @param {string} id
* @returns {RammerheadSession}
*/
add(id) {
if (this.has(id)) throw new Error('the following session already exists: ' + id);
this.logger.debug(`(MemoryStore.add) ${id}`);
const session = new RammerheadSession({ id });
this.mapStore.set(id, session);
return session;
}
/**
* @param {string} id
* @returns {boolean} - returns true when a delete operation is performed
*/
delete(id) {
return this.mapStore.delete(id);
}
/**
* @param {string} id
* @param {string} serializedSession
*/
addSerializedSession(id, serializedSession) {
this.logger.debug(`(MemoryStore.addSerializedSession) adding serialized session id ${id} to store`);
const session = RammerheadSession.DeserializeSession(id, serializedSession);
session.updateLastUsed();
this.mapStore.set(id, session);
this.logger.debug(`(FileCache.addSerializedSession) added ${id}`);
}
delete(id) {
return this.mapStore.delete(id);
}

/**
* @private
Expand Down
6 changes: 3 additions & 3 deletions src/classes/RammerheadProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,9 @@ class RammerheadProxy extends Proxy {
* @private
*/
_setupRammerheadServiceRoutes() {
this.GET('/rammerhead.min.js', {
this.GET('/rammerhead.js', {
content: fs.readFileSync(
path.join(__dirname, '../client/rammerhead.min.js')
path.join(__dirname, '../client/rammerhead' + (process.env.DEVELOPMENT ? '.js' : '.min.js'))
),
contentType: 'application/x-javascript'
});
Expand Down Expand Up @@ -533,7 +533,7 @@ class RammerheadProxy extends Proxy {
*/
GET(route, handler) {
if (route === '/hammerhead.js') {
handler.content = fs.readFileSync(path.join(__dirname, '../client/hammerhead.min.js'));
handler.content = fs.readFileSync(path.join(__dirname, '../client/hammerhead' + (process.env.DEVELOPMENT ? '.js' : '.min.js')));
}
super.GET(route, handler);
}
Expand Down
17 changes: 10 additions & 7 deletions src/classes/RammerheadSession.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ class RammerheadSession extends Session {
* @param {string} options.id
* @param {boolean} options.dontConnectToData - used when we want to connect to data later (or simply don't want to)
* @param {boolean} options.disableShuffling
* @param {string[]} options.prependScripts
*/
constructor({ id = generateId(), dontConnectToData = false, disableShuffling = false } = {}) {
constructor({ id = generateId(), dontConnectToData = false, disableShuffling = false, prependScripts = [] } = {}) {
super(['blah/blah'], {
allowMultipleWindows: true,
disablePageCaching: false
Expand All @@ -41,12 +42,18 @@ class RammerheadSession extends Session {
// console.error(err);
// };

// intellisense //
/**
* @type {{ host: string, hostname: string, bypassRules?: string[]; port?: string; proxyAuth?: string, authHeader?: string } | null}
*/
this.externalProxySettings = null;

// disable http2. error handling from http2 proxy client to non-http2 user is too complicated to handle
// (status code 0, for example, will crash rammerhead)
this.isHttp2Disabled = () => true;

// support localStorage //
this.injectable.scripts.push('/rammerhead.min.js');
this.injectable.scripts.push(...prependScripts);
this.injectable.scripts.push('/rammerhead.js');

this.id = id;
this.shuffleDict = disableShuffling ? null : StrShuffler.generateDictionary();
Expand Down Expand Up @@ -85,10 +92,6 @@ class RammerheadSession extends Session {

const session = new RammerheadSession({ id, dontConnectToData: true });
session.data = parsed.data;
if (!('shuffleDict' in session.data)) {
// here only for updating old versioned sessions
session.data.shuffleDict = null;
}
session.connectHammerheadToData(true);
session.cookies.setJar(parsed.serializedCookieJar);
return session;
Expand Down
1 change: 1 addition & 0 deletions src/classes/RammerheadSessionAbstractStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class RammerheadSessionAbstractStore {
/**
* @abstract
* @param {string} id
* @returns {boolean}
*/
has(id) {
this._mustImplement();
Expand Down
24 changes: 24 additions & 0 deletions src/classes/RammerheadSessionFileCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,28 @@ class RammerheadSessionFileCache extends RammerheadSessionAbstractStore {
.filter((file) => file.endsWith(sessionFileExtension))
.map((file) => file.slice(0, -sessionFileExtension.length));
}
/**
* @returns {string[]} - list of session ids in store
*/
keys() {
let arr = this.keysStore();
for (const id of this.cachedSessions.keys()) {
if (!arr.includes(id)) arr.push(id);
}
return arr;
}
/**
* @param {string} id
* @returns {boolean}
*/
has(id) {
return this.cachedSessions.has(id) || fs.existsSync(this._getSessionFilePath(id));
}
/**
* @param {string} id
* @param {boolean} updateActiveTimestamp
* @returns {RammerheadSession|undefined}
*/
get(id, updateActiveTimestamp = true, cacheToMemory = true) {
if (!this.has(id)) {
this.logger.debug(`(FileCache.get) ${id} does not exist`);
Expand All @@ -97,6 +109,10 @@ class RammerheadSessionFileCache extends RammerheadSessionAbstractStore {

return session;
}
/**
* @param {string} id
* @returns {RammerheadSession}
*/
add(id) {
if (this.has(id)) throw new Error(`session ${id} already exists`);

Expand All @@ -106,6 +122,10 @@ class RammerheadSessionFileCache extends RammerheadSessionAbstractStore {

return this.get(id);
}
/**
* @param {string} id
* @returns {boolean} - returns true when a delete operation is performed
*/
delete(id) {
this.logger.debug(`(FileCache.delete) deleting ${id}`);
if (this.has(id)) {
Expand All @@ -117,6 +137,10 @@ class RammerheadSessionFileCache extends RammerheadSessionAbstractStore {
this.logger.debug(`(FileCache.delete) ${id} does not exist`);
return false;
}
/**
* @param {string} id
* @param {string} serializedSession
*/
addSerializedSession(id, serializedSession) {
this.logger.debug(`(FileCache.addSerializedSession) adding serialized session id ${id} to store`);
const session = RammerheadSession.DeserializeSession(id, serializedSession);
Expand Down
24 changes: 24 additions & 0 deletions src/client/rammerhead.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,26 @@
hookHammerheadStartOnce(main);
// before task.js, we need to add url shuffling
addUrlShuffling();
// and fix iframed proxies
fixProxyEmbed();
}

function main() {
fixUrlRewrite();
fixElementGetter();

// other code if they want to also hook onto hammerhead start //
if (window.rammerheadStartListeners) {
for (const eachListener of window.rammerheadStartListeners) {
try {
eachListener();
} catch (e) {
console.error(e);
}
}
delete window.rammerheadStartListeners;
}

// sync localStorage code //
// disable if other code wants to implement their own localStorage site wrapper
if (window.rammerheadDisableLocalStorageImplementation) {
Expand Down Expand Up @@ -344,6 +358,16 @@
}
}
}
function fixProxyEmbed() {
const originalGet = window['%hammerhead%'].utils.dom.isCrossDomainWindows;
window.overrideIsCrossDomainWindows(function(win1, win2) {
let isCrossDomain = originalGet(win1, win2);
if (!isCrossDomain && ((win1 && !!win1['%hammerhead%']) === (win2 && !!win2['%hammerhead%']))) {
return false;
}
return true;
});
}

function hookHammerheadStartOnce(callback) {
var originalStart = hammerhead.__proto__.start;
Expand Down
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const generateId = require('./util/generateId');
const addStaticFilesToProxy = require('./util/addStaticDirToProxy');
const RammerheadSessionMemoryStore = require('./classes/RammerheadMemoryStore');
const StrShuffler = require('./util/StrShuffler');
const URLPath = require('./util/URLPath');

module.exports = {
RammerheadProxy,
Expand All @@ -17,5 +18,6 @@ module.exports = {
RammerheadSessionFileCache,
StrShuffler,
generateId,
addStaticFilesToProxy
addStaticFilesToProxy,
URLPath
};
2 changes: 2 additions & 0 deletions src/server/setupRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ module.exports = function setupRoutes(proxyServer, sessionStore, logger) {
httpProxy = httpProxy.slice(7);
}
session.setExternalProxySettings(httpProxy);
} else {
session.externalProxySettings = null;
}
if (enableShuffling === '1' && !session.shuffleDict) {
session.shuffleDict = StrShuffler.generateDictionary();
Expand Down
2 changes: 1 addition & 1 deletion src/util/addStaticDirToProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const path = require('path');

// these routes are reserved by hammerhead and rammerhead
const forbiddenRoutes = [
'/rammerhead.min.js',
'/rammerhead.js',
'/hammerhead.js',
'/task.js',
'/iframe-task.js',
Expand Down

0 comments on commit 1d2bcca

Please sign in to comment.