Skip to content

Commit

Permalink
0.9.21
Browse files Browse the repository at this point in the history
  • Loading branch information
ishay-hola committed Dec 11, 2016
1 parent dd8e64d commit cda70f1
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 121 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Luminati Proxy manager - Change Log

- 0.9.21:
- :bug: login/logout issues
- 0.9.20:
- :bug: fix cases with Google sign-in with non-configured proxies
- 0.9.19:
Expand Down
14 changes: 7 additions & 7 deletions bin/pub/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ function root($rootScope, $scope, $http, $window){
});
};
var check_reload = function(){
$http.get('/api/config').error(
$http.get('/api/config').catch(
function(){ setTimeout(check_reload, 500); })
.then(function(){ $window.location.reload(); });
};
Expand All @@ -227,12 +227,12 @@ function root($rootScope, $scope, $http, $window){
text: 'The application will be upgraded and restarted.',
confirmed: function(){
$scope.upgrading = true;
$http.post('/api/upgrade').error(function(){
$http.post('/api/upgrade').catch(function(){
$scope.upgrading = false;
$scope.upgrade_error = true;
}).then(function(data){
$scope.upgrading = false;
$http.post('/api/restart').error(function(){
$http.post('/api/restart').catch(function(){
// $scope.upgrade_error = true;
show_reload();
check_reload();
Expand Down Expand Up @@ -262,7 +262,7 @@ function root($rootScope, $scope, $http, $window){
};
$scope.logout = function(){
$http.post('/api/logout').then(function cb(){
$http.get('/api/config').error(function(){ setTimeout(cb, 500); })
$http.get('/api/config').catch(function(){ setTimeout(cb, 500); })
.then(function(){ $window.location = '/'; });
});
};
Expand Down Expand Up @@ -306,7 +306,7 @@ function config($scope, $http, $window){
});
};
var check_reload = function(){
$http.get('/api/config').error(
$http.get('/api/config').catch(
function(){ setTimeout(check_reload, 500); })
.then(function(){ $window.location.reload(); });
};
Expand Down Expand Up @@ -360,7 +360,7 @@ function resolve($scope, $http, $window){
});
};
var check_reload = function(){
$http.get('/api/config').error(
$http.get('/api/config').catch(
function(){ setTimeout(check_reload, 500); })
.then(function(){ $window.location.reload(); });
};
Expand Down Expand Up @@ -444,7 +444,7 @@ function settings($scope, $http, $window, $sce, $rootScope){
};
$scope.show_password = function(){ $scope.args_password = true; };
var check_reload = function(){
$http.get('/api/config').error(
$http.get('/api/config').catch(
function(){ setTimeout(check_reload, 500); })
.then(function(){ $window.location = '/proxies'; });
};
Expand Down
208 changes: 104 additions & 104 deletions lib/luminati.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,33 +62,6 @@ let write_http_reply = (stream, res, headers)=>{
stream.write(head+'\r\n');
};

let calculate_username = opt=>{
let username = `lum-customer-${opt.customer}-zone-${opt.zone}`;
if (opt.country && opt.country!='*')
username += `-country-${opt.country}`;
if (opt.state && opt.state!='*')
username += '-state-'+opt.state.toLowerCase();
if (opt.city && opt.city!='*')
username += '-city-'+opt.city.toLowerCase().replace(' ', '_');
if (opt.session)
username += `-session-${opt.session}`;
if (opt.asn)
username += `-asn-${opt.asn}`;
if (opt.dns)
username += `-dns-${opt.dns}`;
if (opt.request_timeout)
username += `-timeout-${opt.request_timeout}`;
if (opt.cid)
username += `-cid-${opt.cid}`;
if (opt.ip)
username += `-ip-${opt.ip}`;
if (opt.raw)
username += '-raw';
if (opt.debug)
username += `-debug-${opt.debug}`;
return username;
};

const parse_authorization = header=>{
if (!header)
return;
Expand Down Expand Up @@ -266,6 +239,36 @@ E.prototype.reset_total_stats = function reset_total_stats(){
}
};

E.prototype.calculate_username = function(opt){
opt = assign.apply({}, [this.opt, this, opt].map(o=>_.pick(o||{},
qw`customer zone country state city session asn dns request_timeout
cid ip raw debug password`)));
let username = `lum-customer-${opt.customer}-zone-${opt.zone}`;
if (opt.country && opt.country!='*')
username += `-country-${opt.country}`;
if (opt.state && opt.state!='*')
username += '-state-'+opt.state.toLowerCase();
if (opt.city && opt.city!='*')
username += '-city-'+opt.city.toLowerCase().replace(' ', '_');
if (opt.session)
username += `-session-${opt.session}`;
if (opt.asn)
username += `-asn-${opt.asn}`;
if (opt.dns)
username += `-dns-${opt.dns}`;
if (opt.request_timeout)
username += `-timeout-${opt.request_timeout}`;
if (opt.cid)
username += `-cid-${opt.cid}`;
if (opt.ip)
username += `-ip-${opt.ip}`;
if (opt.raw)
username += '-raw';
if (opt.debug)
username += `-debug-${opt.debug}`;
return {username: username, password: opt.password};
};

E.prototype._handler = etask._fn(
function*_handler(_this, req, res, head){
_this.active++;
Expand Down Expand Up @@ -301,37 +304,6 @@ function*_handler(_this, req, res, head){
_this.throttle_queue.push(this);
yield this.wait();
}
if (_this.opt.pool_size && !req.headers['proxy-authorization'])
{
if (!_this.sessions)
{
_this.sessions = [];
yield _this._pool(_this.opt.pool_size);
_this._log.debug(`initialized pool - ${_this.opt.pool_size}`);
_this._pool_ready = true;
}
else
{
if (_this._pool_ready)
{
if (!_this.sessions.length)
{
_this._log.warn('pool size is too small');
yield _this._pool_fetch();
}
}
for (;; yield etask.sleep(1000))
{
if (!_this._pool_ready)
continue;
if (_this.sessions.length)
break;
_this._log.warn('pool size is too small');
yield _this._pool_fetch();
break;
}
}
}
if (_this.opt.only_bypass || _this.hosts.length)
return yield _this._request(req, res, head);
_this.requests_queue.push([req, res, head]);
Expand Down Expand Up @@ -607,12 +579,10 @@ E.prototype._pool_fetch = etask._fn(function*pool_fetch(_this, retries){
yield etask.sleep(10000);
}
let session_id = `${_this.port}_${_this.session_id++}`;
let username = calculate_username(assign({session: session_id},
_.pick(_this.opt, qw`customer zone country state city asn cid
ip raw dns debug request_timeout`)));
let cred = _this.calculate_username({session: session_id});
let host = _this.hosts.shift();
_this.hosts.push(host);
let proxy_url = `http://${username}:${_this.password}@${host}:${_this.opt.proxy_port}`;
let proxy_url = `http://${cred.username}:${cred.password}@${host}:${_this.opt.proxy_port}`;
let session = {
host: host,
session: session_id,
Expand All @@ -621,7 +591,7 @@ E.prototype._pool_fetch = etask._fn(function*pool_fetch(_this, retries){
created: new Date().getTime(),
proxy_url: proxy_url,
stats: true,
username: username,
username: cred.username,
};
_this._log.debug(`establishing new session ${host}:${session_id}`);
let err, res;
Expand Down Expand Up @@ -715,14 +685,40 @@ E.prototype.stop_keep_alive = function(session){
session.keep_alive = null;
};

E.prototype._request_session = etask._fn(function*request_session(_this, req, only){
let authorization = _this.opt.allow_proxy_auth &&
parse_authorization(req.headers['proxy-authorization']);
delete req.headers['proxy-authorization'];
E.prototype._request_session = etask._fn(function*request_session(_this, req, auth_header, only){
if (only)
return;
if (!authorization && _this.sessions && _this.sessions.length)
const authorization = _this.opt.allow_proxy_auth && parse_authorization(auth_header);
if (!authorization && _this.opt.pool_size)
{
if (!_this.sessions)
{
_this.sessions = [];
yield _this._pool(_this.opt.pool_size);
_this._log.debug(`initialized pool - ${_this.opt.pool_size}`);
_this._pool_ready = true;
}
else
{
if (_this._pool_ready)
{
if (!_this.sessions.length)
{
_this._log.warn('pool size is too small');
yield _this._pool_fetch();
}
}
for (;; yield etask.sleep(1000))
{
if (!_this._pool_ready)
continue;
if (_this.sessions.length)
break;
_this._log.warn('pool size is too small');
yield _this._pool_fetch();
break;
}
}
let session = _this.sessions[0];
_this.set_keep_alive(session);
if (_this.pool_type==E.pool_types['round-robin'])
Expand Down Expand Up @@ -796,11 +792,45 @@ E.prototype._request = etask._fn(function*_request(_this, req, res, head){
let _url = req.url, only = _this.opt.only_bypass;
const context = res.x_hola_context = req.headers['x-hola-context'];
delete req.headers['x-hola-context'];
const auth_header = req.headers['proxy-authorization'];
delete req.headers['proxy-authorization'];
const timeline = {start: Date.now()};
const headers = assign({}, req.headers);
for (let i=0; i<req.rawHeaders.length; i+=2)
{
let raw_header = req.rawHeaders[i];
let norm_header = raw_header.toLowerCase();
if (raw_header!=norm_header && headers[norm_header])
{
headers[raw_header] = headers[norm_header];
delete headers[norm_header];
}
}
const response = {
request: {
method: req.method,
url: _url,
headers: headers,
raw_headers: req.rawHeaders,
body: '',
},
timeline: timeline,
body_size: 0,
stats: {
inbound: 0,
outbound: 0,
},
context: context,
};
let send_null_response = ()=>{
_this._log.debug(`Returning null response: ${req.method} ${_url}`);
let status = req.method=='CONNECT' ? 501 : 200;
write_http_reply(res, {statusCode: status, statusMessage: 'NULL'});
res.end();
timeline.end = Date.now() - timeline.start;
response.status_code = status;
response.status_message = 'NULL';
_this.emit('response', response);
};
if (req.method=='CONNECT')
{
Expand All @@ -823,44 +853,16 @@ E.prototype._request = etask._fn(function*_request(_this, req, res, head){
_this._log.error('invalid host!!!');
return _this.emit('error', 'No hosts when processing request');
}
let session = yield _this._request_session(req, only);
let session = yield _this._request_session(req, auth_header, only);
let host = session&&session.host || (only ? '127.0.0.1' : _this.hosts[0]);
let stats = only ? get_zero_stats() : _this.stats[host];
if (!stats)
{
_this._log.error('invalid host!!!', host);
return _this.emit('error', 'No stats for host');
}
const timeline = {start: Date.now()};
stats.active_requests++;
stats.max_requests = Math.max(stats.max_requests, stats.active_requests);
const headers = assign({}, req.headers);
for (let i=0; i<req.rawHeaders.length; i+=2)
{
let raw_header = req.rawHeaders[i];
let norm_header = raw_header.toLowerCase();
if (raw_header!=norm_header && headers[norm_header])
{
headers[raw_header] = headers[norm_header];
delete headers[norm_header];
}
}
const response = {
request: {
method: req.method,
url: _url,
headers: headers,
raw_headers: req.rawHeaders,
body: '',
},
timeline: timeline,
body_size: 0,
stats: {
inbound: 0,
outbound: 0,
},
context: context,
};
request_stats(req, res, rstats=>{
stats.total_requests++;
const downloaded = rstats.res.bytes;
Expand Down Expand Up @@ -1001,19 +1003,17 @@ E.prototype._request = etask._fn(function*_request(_this, req, res, head){
}
else if (only)
return send_null_response();
let username = calculate_username(assign({}, _this.opt, {
let cred = _this.calculate_username(assign({}, {
session: session.session,
}, session.authorization||{}, _.pick(_this.opt, 'customer')));
let password = _this.opt.password ||
session.authorization && session.authorization.password;
_this._log.debug(`requesting using ${username}`);
}, session.authorization||{}));
_this._log.debug(`requesting using ${cred.username}`);
response.proxy = {
host: host,
username: username,
username: cred.username,
};
const connect_headers = {
'proxy-authorization': 'Basic '+
new Buffer(username+':'+password).toString('base64'),
new Buffer(cred.username+':'+cred.password).toString('base64'),
'x-hola-agent': version,
};
if (req.socket instanceof tls.TLSSocket)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "luminati-proxy",
"version": "0.9.20",
"version": "0.9.21",
"description": "A configurable local proxy for luminati.io",
"homepage": "https://luminati.io/",
"main": "index.js",
Expand Down
Loading

0 comments on commit cda70f1

Please sign in to comment.