mirror2
Version:
a serious series of tubes
393 lines (363 loc) • 12.3 kB
JavaScript
// Generated by IcedCoffeeScript 108.0.12
(function() {
var Proxy, connect, harmon, http, httpProxy, iced, log, logger, mitm, _, __iced_k, __iced_k_noop,
__slice = [].slice,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
iced = {
Deferrals: (function() {
function _Class(_arg) {
this.continuation = _arg;
this.count = 1;
this.ret = null;
}
_Class.prototype._fulfill = function() {
if (!--this.count) {
return this.continuation(this.ret);
}
};
_Class.prototype.defer = function(defer_params) {
++this.count;
return (function(_this) {
return function() {
var inner_params, _ref;
inner_params = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
if (defer_params != null) {
if ((_ref = defer_params.assign_fn) != null) {
_ref.apply(null, inner_params);
}
}
return _this._fulfill();
};
})(this);
};
return _Class;
})(),
findDeferral: function() {
return null;
},
trampoline: function(_fn) {
return _fn();
}
};
__iced_k = __iced_k_noop = function() {};
log = function() {
var x;
x = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
try {
return console.log.apply(console, x);
} catch (_error) {}
};
logger = require('./logger');
_ = require('wegweg')({
globals: false,
shelljs: false
});
http = require('http');
harmon = require('harmon');
connect = require('connect');
mitm = require('http-mitm-proxy');
httpProxy = require('http-proxy');
module.exports = Proxy = (function(_super) {
__extends(Proxy, _super);
Proxy.prototype._used_ports = [];
function Proxy(opt) {
var _base, _base1, _base2;
this.opt = opt != null ? opt : {};
if ((_base = this.opt).host == null) {
_base.host = "stackoverflow.com";
}
if ((_base1 = this.opt).silent == null) {
_base1.silent = false;
}
if (!this.opt.silent) {
this.setup_loggers();
}
if ((_base2 = this.opt).hide_error_stack == null) {
_base2.hide_error_stack = true;
}
}
Proxy.prototype.setup = function(cb) {
var e, open_port, ___iced_passed_deferral, __iced_deferrals, __iced_k;
__iced_k = __iced_k_noop;
___iced_passed_deferral = iced.findDeferral(arguments);
(function(_this) {
return (function(__iced_k) {
if (!_this.opt.proxy_port) {
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/home/taky/www/mirror-mirror/src/lib/proxy.iced",
funcname: "Proxy.setup"
});
_this._find_port(__iced_deferrals.defer({
assign_fn: (function() {
return function() {
e = arguments[0];
return open_port = arguments[1];
};
})(),
lineno: 27
}));
__iced_deferrals._fulfill();
})(function() {
_this.opt.proxy_port = open_port;
return __iced_k(_this._used_ports.push(open_port));
});
} else {
return __iced_k();
}
});
})(this)((function(_this) {
return function() {
(function(__iced_k) {
if (!_this.opt.port) {
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/home/taky/www/mirror-mirror/src/lib/proxy.iced",
funcname: "Proxy.setup"
});
_this._find_port(__iced_deferrals.defer({
assign_fn: (function() {
return function() {
e = arguments[0];
return open_port = arguments[1];
};
})(),
lineno: 32
}));
__iced_deferrals._fulfill();
})(function() {
_this.opt.port = open_port;
return __iced_k(_this._used_ports.push(open_port));
});
} else {
return __iced_k();
}
})(function() {
_this.port = _this.opt.port;
_this.proxy_port = _this.opt.proxy_port;
_this.setup_proxy();
_this.setup_http();
return cb(null, _this.opt);
});
};
})(this));
};
Proxy.prototype.setup_loggers = function() {
var request_events, spawn_events, x, _fn, _i, _j, _len, _len1, _results;
this.on('error', function(e) {
return logger.error(e);
});
request_events = ['request', 'request_ignored', 'request_delivered'];
_fn = (function(_this) {
return function(x) {
return _this.on(x, function(req) {
var verb;
verb = 'info';
if (x === 'request_ignored') {
verb = 'warn';
}
return logger[verb](x, {
url: req.url,
method: req.method
});
});
};
})(this);
for (_i = 0, _len = request_events.length; _i < _len; _i++) {
x = request_events[_i];
_fn(x);
}
spawn_events = ['proxy_listening'];
_results = [];
for (_j = 0, _len1 = spawn_events.length; _j < _len1; _j++) {
x = spawn_events[_j];
_results.push((function(_this) {
return function(x) {
return _this.on(x, function(data) {
return logger.info(x, data);
});
};
})(this)(x));
}
return _results;
};
Proxy.prototype.setup_proxy = function() {
this.proxy = mitm();
this.proxy.use(mitm.gunzip);
return this.proxy.onRequest((function(_this) {
return function(ctx, cb) {
var chunks;
_this.emit('request', ctx.clientToProxyRequest);
chunks = [];
ctx.isSSL = false;
if (_this.opt.enable_ssl) {
ctx.isSSL = true;
ctx.proxyToServerRequestOptions.agent = _this.proxy.httpsAgent;
ctx.proxyToServerRequestOptions.port = '443';
}
ctx.proxyToServerRequestOptions.headers['accept-encoding'] = 'gzip';
ctx.onResponseData(function(ctx, chunk, next) {
chunks.push(chunk);
return next();
});
ctx.onResponseEnd(function(ctx, next) {
var body, bulk, content_type, modifier, url, _end, _i, _len, _ref, _ref1, _ref2, _ref3;
body = Buffer.concat(chunks);
bulk = body.toString();
url = ctx.clientToProxyRequest.url;
_end = (function(s) {
ctx.proxyToClientResponse.write(s);
return next();
});
if (!bulk.includes('</head>')) {
return _end(body);
}
content_type = (_ref = (_ref1 = ctx.serverToProxyResponse.headers) != null ? _ref1['content-type'] : void 0) != null ? _ref : 'none';
if (!(content_type.indexOf('text/html') > -1)) {
return _end(body);
}
if (_this.opt.append_head) {
bulk = bulk.replace(/<\/head>/g, _this.opt.append_head + '</head>');
}
if ((_ref2 = _this.opt.html_modifiers) != null ? _ref2.length : void 0) {
_ref3 = _this.opt.html_modifiers;
for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
modifier = _ref3[_i];
bulk = modifier(bulk);
}
}
return _end(bulk);
});
return cb();
};
})(this));
};
Proxy.prototype.setup_http = function() {
var app, selects, x, _i, _len, _ref, _ref1, _ref2, _rewrite;
this.http_proxy = httpProxy.createProxyServer({
ws: true,
xfwd: true,
autoRewrite: true,
hostRewrite: true,
secure: false
});
this.http_proxy.on('error', (function(_this) {
return function(e) {
return _this.emit('error', e);
};
})(this));
_rewrite = (function(_this) {
return function(attr_name, node) {
var attr, new_value, x, _i, _len, _ref;
attr = node.getAttribute(attr_name);
if (!(attr != null ? typeof attr.includes === "function" ? attr.includes(_this.opt.host) : void 0 : void 0)) {
return;
}
new_value = attr;
_ref = ['https://', 'http://', '//'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
x = _ref[_i];
if (new_value.startsWith(x + _this.opt.host)) {
new_value = new_value.substr((x + _this.opt.host).length);
}
}
return node.setAttribute(attr_name, new_value);
};
})(this);
selects = [
{
query: 'a, link',
func: ((function(_this) {
return function(node) {
return _rewrite('href', node);
};
})(this))
}, {
query: 'img, script',
func: ((function(_this) {
return function(node) {
return _rewrite('src', node);
};
})(this))
}
];
if ((_ref = this.opt.harmon_selects) != null ? _ref.length : void 0) {
selects = selects.concat(this.opt.harmon_selects);
}
app = connect();
app.use(harmon([], selects, true));
if ((_ref1 = this.opt.middleware) != null ? _ref1.length : void 0) {
_ref2 = this.opt.middleware;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
x = _ref2[_i];
app.use(x);
}
}
app.use(((function(_this) {
return function(req, res, next) {
var request_opts;
req.headers.host = _this.opt.host;
request_opts = {
target: 'http://127.0.0.1:' + _this.opt.proxy_port
};
_this.emit('request_delivered', req);
return _this.http_proxy.web(req, res, request_opts, function(e) {
return next(e);
});
};
})(this)));
app.use(((function(_this) {
return function(err, req, res, next) {
var _ref3;
_this.emit('error', err);
res.statusCode = (_ref3 = req._code) != null ? _ref3 : 500;
if (_this.opt.hide_error_stack) {
return res.end(err.toString());
} else {
return next();
}
};
})(this)));
return this.http = http.createServer(app);
};
Proxy.prototype.listen = function() {
var prox_opt;
prox_opt = {
port: this.opt.proxy_port
};
if (this.opt.proxy) {
prox_opt.httpAgent = new require('proxy-agent')(this.opt.proxy);
prox_opt.httpsAgent = new require('proxy-agent')(this.opt.proxy);
}
this.proxy.listen(prox_opt);
this.http.listen(this.opt.port);
return this.emit('proxy_listening', this.opt);
};
Proxy.prototype._find_port = function(cb) {
var derp;
derp = require('net').createServer();
return derp.listen(0, (function(_this) {
return function() {
var port;
port = derp.address().port;
derp.close();
return cb(null, port);
};
})(this));
};
return Proxy;
})((require('events').EventEmitter));
/*
if !module.parent
p = new Proxy {
host: 'greatist.com'
port: 8009
}
await p.setup defer()
p.listen()
log ":8009"
*/
}).call(this);