Skip to content
Merged

ES6 #70

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
env:
node: true
mocha: true
es6: true

rules:
# Possible Errors
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM mhart/alpine-node
FROM mhart/alpine-node:8

MAINTAINER Dmitry Shirokov <[email protected]>

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ npm --proxy http://npm-proxy-cache:8080 --https-proxy http://npm-proxy-cache:808

## Limitations

- Works only with node `0.10` and above.
- Works only with node `4.9.1` and above.


----
Expand Down
47 changes: 25 additions & 22 deletions lib/cache.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
'use strict';
var path = require('path'),
fs = require('fs'),
os = require('os'),
crypto = require('crypto'),
mkdirp = require('mkdirp'),
mv = require('mv');
const path = require('path');
const fs = require('fs');
const os = require('os');
const crypto = require('crypto');
const mkdirp = require('mkdirp');
const mv = require('mv');

function Cache(opts) {
this.opts = opts || {};
Expand All @@ -13,13 +13,13 @@ function Cache(opts) {
this.opts.path = opts.path || path.join(__dirname, '/../cache');

this.locks = {};
var nop = function() {};
const nop = function() {};

this.stat = function(fullpath) {
if (!fs.existsSync(fullpath))
return {status: Cache.NOT_FOUND};

var stat = fs.lstatSync(fullpath);
const stat = fs.lstatSync(fullpath);
stat.type = path.extname(fullpath) ? 'application/octet-stream' : 'application/json';
stat.status = (Date.now() < stat.ctime.valueOf() + this.opts.ttl)
? Cache.FRESH
Expand All @@ -30,9 +30,9 @@ function Cache(opts) {


this.meta = function(key, cb) {
var self = this,
fullpath = this.getPath(key).full,
stat = this.stat(fullpath);
const self = this;
const fullpath = this.getPath(key).full;
const stat = this.stat(fullpath);

if (stat.status === Cache.NOT_FOUND || stat.status === Cache.EXPIRED)
return cb(null, stat);
Expand All @@ -53,8 +53,8 @@ function Cache(opts) {


this.read = function(key) {
var pathInfo = this.getPath(key),
file = fs.createReadStream(pathInfo.full);
const pathInfo = this.getPath(key);
const file = fs.createReadStream(pathInfo.full);

file.on('finish', function() {
file.close(nop);
Expand All @@ -65,9 +65,9 @@ function Cache(opts) {


this.write = function(key, readStream, cb) {
var locks = this.locks,
pathInfo = this.getPath(key),
self = this;
const locks = this.locks;
const pathInfo = this.getPath(key);
const self = this;

// Create a lock
locks[key] = true;
Expand All @@ -76,9 +76,9 @@ function Cache(opts) {

// On top of locking mechanism, doing write to a temp location, and
// when it's finish moving the data file to its final destination.
var tmpPath = path.join(os.tmpdir(), pathInfo.file + '-' + Math.round(Math.random() * 1e9).toString(36));
const tmpPath = path.join(os.tmpdir(), pathInfo.file + '-' + Math.round(Math.random() * 1e9).toString(36));

var writeStream = fs.createWriteStream(tmpPath);
const writeStream = fs.createWriteStream(tmpPath);
readStream.pipe(writeStream);

writeStream.on('finish', function() {
Expand All @@ -95,7 +95,9 @@ function Cache(opts) {


this.getPath = function(key) {
var file, base, chunks, dir;
let file;
let base;

if (this.opts.friendlyNames) {
// The key is the URL; the last part is the module name and if
// the last version is requested, it lacks the file extension
Expand All @@ -106,15 +108,16 @@ function Cache(opts) {
base = file.replace(/(-\d\.\d.\d)?\.tgz/, '').replace(/\./g, '-');
} else {
file = crypto.createHash('md5').update(key).digest('hex')
.substring(0, 8) + path.extname(key);
.substring(0, 8) + path.extname(key);

base = file;
}
// Make sure that there are always 3 nested directories to avoid
// both file and folder at the same level (/q/q, /q/q/qq)
chunks = base.split('').splice(0, 3);
const chunks = base.split('').splice(0, 3);
while (chunks.length < 3)
chunks.push('-');
dir = chunks.join('/');
const dir = chunks.join('/');

return {
dir: path.join(this.opts.path, dir),
Expand Down
59 changes: 29 additions & 30 deletions lib/proxy.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
'use strict';
var http = require('http'),
net = require('net'),
https = require('https'),
fs = require('fs'),
os = require('os'),
url = require('url'),
path = require('path'),
request = require('request'),
log4js = require('log4js');

var Cache = require('./cache');
const http = require('http');
const net = require('net');
const https = require('https');
const fs = require('fs');
const os = require('os');
const url = require('url');
const path = require('path');
const request = require('request');
const log4js = require('log4js');
const Cache = require('./cache');


// To avoid 'DEPTH_ZERO_SELF_SIGNED_CERT' error on some setups
Expand All @@ -22,16 +21,16 @@ exports.cache = null;
exports.opts = {};

// Port or socket path of internal MITM server.
var mitmAddress;
let mitmAddress;

// Random header to prevent sending requests in a cycle
var cycleCheckHeader = 'x-npm-proxy-cache-' + Math.round(Math.random() * 10000);
const cycleCheckHeader = 'x-npm-proxy-cache-' + Math.round(Math.random() * 10000);

exports.powerup = function(opts) {

exports.opts = opts || {};

var options = {
const options = {
key: fs.readFileSync(path.join(__dirname, '/../cert/dummy.key'), 'utf8'),
cert: fs.readFileSync(path.join(__dirname, '/../cert/dummy.crt'), 'utf8')
};
Expand All @@ -49,7 +48,7 @@ exports.powerup = function(opts) {
}

// Fake https server aka MITM
var mitm = https.createServer(options, exports.httpHandler);
const mitm = https.createServer(options, exports.httpHandler);

// NOTE: for windows platform user has to specify port, since
// it does not support unix sockets.
Expand All @@ -72,7 +71,7 @@ exports.powerup = function(opts) {
mitm.listen(mitmAddress);

// start HTTP server with custom request handler callback function
var server = http.createServer(exports.httpHandler).listen(opts.port, opts.host, function(err) {
const server = http.createServer(exports.httpHandler).listen(opts.port, opts.host, function(err) {
if (err) throw err;
exports.log.info('Listening on %s:%s [%d]', opts.host, opts.port, process.pid);
});
Expand All @@ -85,7 +84,7 @@ exports.powerup = function(opts) {


exports.httpHandler = function(req, res) {
var cache = exports.cache,
const cache = exports.cache,
log = exports.log,
path = url.parse(req.url).path,
schema = req.client.pair || req.connection.encrypted ? 'https' : 'http',
Expand All @@ -97,7 +96,7 @@ exports.httpHandler = function(req, res) {
return;
}

var params = {
const params = {
headers: {},
rejectUnauthorized: false,
url: dest
Expand All @@ -106,7 +105,7 @@ exports.httpHandler = function(req, res) {
params.headers[cycleCheckHeader] = 1;

// Carry following headers down to dest npm repository.
var carryHeaders = ['authorization', 'version', 'referer', 'npm-session', 'user-agent'];
const carryHeaders = ['authorization', 'version', 'referer', 'npm-session', 'user-agent'];
carryHeaders.forEach(function(name) {
params.headers[name] = req.headers[name];
});
Expand All @@ -131,12 +130,12 @@ exports.httpHandler = function(req, res) {
if (meta.status === Cache.FRESH)
return respondWithCache(dest, cache, meta, res);

var p = cache.getPath(dest);
const p = cache.getPath(dest);
log.debug('Cache file:', p.rel);

log.warn('direct', dest);

var onResponse = function(err, response) {
const onResponse = function(err, response) {
// don't save responses with codes other than 200
if (!err && response.statusCode === 200) {
cache.write(dest, r, function(err, meta) {
Expand Down Expand Up @@ -164,7 +163,7 @@ exports.httpHandler = function(req, res) {
}
};

var r = request(params);
const r = request(params);
r.on('response', onResponse.bind(null, null));
r.on('error', onResponse.bind(null));
r.on('end', function() {
Expand All @@ -175,13 +174,13 @@ exports.httpHandler = function(req, res) {


exports.httpsHandler = function(request, socketRequest, bodyhead) {
var log = exports.log,
const log = exports.log,
httpVersion = request['httpVersion'];

log.debug(' = will connect to socket (or port) "%s"', mitmAddress);

// set up TCP connection
var proxySocket = new net.Socket();
const proxySocket = new net.Socket();
proxySocket.connect(mitmAddress, function() {
log.debug('< connected to socket (or port) "%s"', mitmAddress);
log.debug('> writing head of length %d', bodyhead.length);
Expand Down Expand Up @@ -226,10 +225,10 @@ exports.httpsHandler = function(request, socketRequest, bodyhead) {


function bypass(req, res, params) {
var length = parseInt(req.headers['content-length']);
var log = exports.log;
const length = parseInt(req.headers['content-length']);
const log = exports.log;

var onEnd = function(params, res) {
const onEnd = function(params, res) {
return request(params)
.on('error', function(err) {
log.error('bypass', err);
Expand All @@ -242,8 +241,8 @@ function bypass(req, res, params) {
return;
}

var raw = new Buffer(length),
pointer = 0;
const raw = new Buffer(length);
let pointer = 0;

req.on('data', function(chunk) {
chunk.copy(raw, pointer);
Expand All @@ -264,7 +263,7 @@ function bypass(req, res, params) {


function respondWithCache(dest, cache, meta, res) {
var log = exports.log;
const log = exports.log;
log.info('cache', dest);
log.debug('size: %s, type: "%s", ctime: %d', meta.size, meta.type, meta.ctime.valueOf());
res.setHeader('Content-Length', meta.size);
Expand Down
Loading