├── .gitignore ├── README.md ├── bin ├── main.js └── node-http-proxy ├── index.js ├── lib ├── common.js ├── proxy-master.js └── proxy-server.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | node_modules/ 3 | test/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | node-http-proxy 2 | =============== 3 | 4 | a node http(s) proxy server with single process mode or multi process mode(set parameter '-i') 5 | 6 | ## Install node-http-proxy 7 | 8 | ```bash 9 | $npm install -g node-http-proxy 10 | ``` 11 | 12 | ## Server Start 13 | 14 | ```bash 15 | $nproxy start -p 9999 -i 1 16 | #start proxy server 17 | #create child process 1 (default 1) or more(limit by cpu cores) 18 | #on port 9999(default 8234) 19 | 20 | $nproxy stop #stop server 21 | 22 | ``` 23 | 24 | ## Use in code 25 | ```javascript 26 | var ProxyMaster = require('node-http-proxy').proxyMaster; 27 | 28 | var proxymaster = new ProxyMaster({instance:1,port:8123}); 29 | 30 | proxymaster.start(); 31 | ``` 32 | 33 | 34 | ## Useage 35 | ```bash 36 | $curl -x 127.0.0.1:9999 http://www.google.com/ 37 | ``` 38 | 39 | ## Something need to do 40 | 41 | 1.finished nproxy command
42 | 2.support other http method 43 | -------------------------------------------------------------------------------- /bin/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * tu run proxy-server 3 | * Created by wddqing on 15/2/3. 4 | */ 5 | 6 | //console.log(process.argv); 7 | var commander = require('commander'); 8 | commander.option('-p --port [i]') 9 | .option('-i --instance [i]') 10 | .parse(process.argv); 11 | var argv = {}; 12 | 13 | ['instance','port'].forEach(function(k){ 14 | if(commander[k] != undefined){ 15 | argv[k] = commander[k]; 16 | } 17 | }); 18 | 19 | var ProxyMaster = require('../lib/proxy-master') 20 | 21 | var proxymaster = new ProxyMaster(argv) 22 | 23 | proxymaster.start(); 24 | -------------------------------------------------------------------------------- /bin/node-http-proxy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict'; 4 | 5 | var program = require('commander'); 6 | var os = require('os'); 7 | var cp = require('child_process'); 8 | var fs = require('fs'); 9 | 10 | var common = require('../lib/common'); 11 | var SERVER_ENV = common.SERVER_ENV; 12 | var PID = SERVER_ENV.PID; 13 | var VERSION = SERVER_ENV.VERSION; 14 | 15 | program.on('--help',function(){ 16 | console.log(" ================Basic Example==============="); 17 | console.log(''); 18 | console.log(' SERVER START'); 19 | console.log(' $nproxy start -p 8888 -i 1'); 20 | console.log(''); 21 | console.log(' SERVER STOP'); 22 | console.log(' $nproxy stop'); 23 | console.log(''); 24 | console.log(' view more detail at http://github.com/wddqing/node-http-proxy'); 25 | console.log(''); 26 | }); 27 | 28 | 29 | //set version 30 | program.version(VERSION); 31 | 32 | //program command 33 | program.command('start') 34 | .description('start server') 35 | .option('-i --instance ','child process,0 means use max cpu cores',function(i){ 36 | //check instance size 37 | var cores = os.cpus().length; 38 | return i > cores? cores : i>0 ? i : 1 39 | }) 40 | .option('-p --port

','listen port') 41 | .option('-D --debug','set debug level') 42 | .action(function(cmd){ 43 | if(fs.existsSync(PID)){ 44 | var pid = fs.readFileSync(PID); 45 | console.log('stop nproxy pid',Number(pid)); 46 | try{ 47 | process.kill(Number(fs.readFileSync(PID),'SIGTERM')); 48 | fs.unlinkSync(PID); 49 | }catch(e){ 50 | console.log('server stop error',e) 51 | } 52 | } 53 | 54 | var cp_opt = { 55 | stdio: ['ignore', 'ignore', 'ignore'], 56 | env: process.env, 57 | cwd: process.cwd(), 58 | detached: true 59 | }; 60 | try{ 61 | var argv = ['-p',cmd.port || 8845,'-i',cmd.instance || os.cpus().length ,cmd.debug]; 62 | var child = cp.spawn(process.execPath,[__dirname+'/main.js'].concat(argv),cp_opt); 63 | console.log('start process nproxy',child.pid,'pid file',PID); 64 | fs.writeFileSync(PID,child.pid); 65 | child.unref(); 66 | }catch(e){ 67 | console.log('server start error',e) 68 | } 69 | process.exit(0); 70 | }); 71 | 72 | program.command('stop') 73 | .description('stop server') 74 | .action(function(cmd){ 75 | if(fs.existsSync(PID)){ 76 | var pid = fs.readFileSync(PID); 77 | console.log('stop nproxy pid',Number(pid)); 78 | try{ 79 | process.kill(Number(fs.readFileSync(PID),'SIGTERM')); 80 | fs.unlinkSync(PID); 81 | }catch(e){ 82 | console.log('server stop error',e) 83 | } 84 | } 85 | process.exit(0) 86 | }); 87 | 88 | program.command('*') 89 | .action(function(cmd){ 90 | console.log(' use --help for command usage') 91 | }); 92 | 93 | //parse argv 94 | program.parse(process.argv); 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | var proxyMaster = require('./lib/proxy-master') 3 | var fs = require('fs') 4 | 5 | 6 | module.exports = { 7 | proxyMaster:proxyMaster 8 | } 9 | -------------------------------------------------------------------------------- /lib/common.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by wddqing on 15/2/3. 3 | */ 4 | 5 | 6 | module.exports = { 7 | 'SERVER_ENV':{ 8 | 'NAME':'node-http-proxy', 9 | 'VERSION':'0.2.3', 10 | 'PID':'/tmp/node-http-proxy.pid' 11 | } 12 | } -------------------------------------------------------------------------------- /lib/proxy-master.js: -------------------------------------------------------------------------------- 1 | /** 2 | * master to manage proxy nodes 3 | * @type {exports} 4 | */ 5 | 6 | var pm = require('pm'); 7 | 8 | function proxyMaster(options){ 9 | this._options = options || {}; 10 | this._app = pm.createMaster({ 11 | 'pidfile' : '/tmp/node-proxy-server.pid' 12 | }) 13 | } 14 | 15 | proxyMaster.prototype.start = function(){ 16 | var options = this._options 17 | 18 | this._app.register('proxy-server',__dirname + '/proxy-server.js', { 19 | listen : options.port || 8234, 20 | children: options.instance || 1 21 | },process.argv) 22 | 23 | this._app.on('giveup', function (name, num, pause) { 24 | console.log('giveup', name, num, pause) 25 | }) 26 | 27 | this._app.dispatch() 28 | } 29 | 30 | proxyMaster.prototype.stop = function(){ 31 | 32 | } 33 | 34 | module.exports = proxyMaster 35 | -------------------------------------------------------------------------------- /lib/proxy-server.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var Socket = require('net').Socket; 3 | var url = require('url'); 4 | var dns = require('dns'); 5 | var request = require('request'); 6 | var qs = require('querystring'); 7 | var pm = require('pm'); 8 | var BufferHelper = require('bufferhelper'); 9 | 10 | 11 | (function proxy(){ 12 | this.options = {}; 13 | this.proxyNode = new proxyNode(this.options); 14 | 15 | 16 | function proxyNode(options){ 17 | //初始化Node服务器 18 | this.httpProxy = new httpProxy(options); 19 | this.httpsProxy = new httpsProxy(options); 20 | var server = http.createServer(serverHandler); 21 | this.httpProxy.init(server); 22 | this.httpsProxy.init(server); 23 | } 24 | 25 | function serverHandler(req,res){ 26 | headerProcessor(req.headers); 27 | var options = {headers:req.headers,followRedirect:false,timeout:30000}; 28 | switch(req.method.toLowerCase()){ 29 | case 'post': 30 | var bufferhelper = new BufferHelper(); 31 | bufferhelper.load(req,function(err,body){ 32 | options.form = qs.parse(body); 33 | request_handler('post',req,options,res); 34 | }); 35 | break; 36 | case 'get': 37 | request_handler('get',req,options,res); 38 | break; 39 | default: 40 | res.end('no support method'); 41 | break; 42 | } 43 | } 44 | 45 | function request_handler(method,req,options,res){ 46 | var r = request[method](req.url,options); 47 | r.on('error',function(e){ 48 | if(argv.log_error) 49 | console.trace(e); 50 | res.end(); 51 | }); 52 | r.pipe(res); 53 | } 54 | 55 | 56 | function headerProcessor(headers) { 57 | 58 | function normalizeHeaderCase(header){ 59 | var result = { 60 | "content-md5": "Content-MD5", 61 | "dnt": "DNT", 62 | "etag": "ETag", 63 | "last-event-id": "Last-Event-ID", 64 | "tcn": "TCN", 65 | "te": "TE", 66 | "www-authenticate": "WWW-Authenticate", 67 | "x-dnsprefetch-control": "X-DNSPrefetch-Control" 68 | }[header.toLowerCase()]; 69 | if (result) { 70 | return result; 71 | } 72 | return header 73 | .split("-") 74 | .map(function (text) { 75 | return text.charAt(0).toUpperCase() + text.substr(1).toLowerCase(); 76 | }) 77 | .join("-"); 78 | } 79 | Object.keys(headers).forEach(function(h){ 80 | var k = normalizeHeaderCase(h); 81 | if(k != h){ 82 | headers[k] = headers[h]; 83 | delete headers[h]; 84 | } 85 | }); 86 | } 87 | 88 | function httpProxy(options){ 89 | //初始化http代理模块 90 | this.init = function(server){ 91 | pm.createWorker().ready(function (socket, port) { 92 | server.emit('connection', socket); 93 | }); 94 | } 95 | } 96 | 97 | 98 | 99 | function httpsProxy(options){ 100 | //初始化https代理模块 101 | 102 | function targetReceiver(hosts,ua){ 103 | var target = new Socket();//target socket 104 | target.setTimeout(10000,function(){ 105 | target.destroy(); 106 | }); 107 | ua.on('error',function(e){ 108 | if(argv.log_error) 109 | console.trace(e); 110 | }); 111 | target.on('error',function(e){ 112 | if(argv.log_error) 113 | console.trace(e); 114 | }); 115 | target.on('close',function(){ 116 | ua.destroy(); 117 | }); 118 | ua.on('close',function(){ 119 | target.destroy(); 120 | }); 121 | 122 | target.on('connect',function(){ 123 | if(ua.write('HTTP/1.1 200 Connection Established\r\n\r\n')){ 124 | ua.pipe(target); 125 | target.pipe(ua); 126 | }else{ 127 | target.destroy(); 128 | } 129 | }); 130 | target.connect(hosts.port,hosts.host); 131 | 132 | } 133 | function connection_handler(req,ua,head){ 134 | var hosts = url.parse('https://'+req.headers.host); 135 | if(hosts == undefined || !hosts){//have not target host 136 | return ua.end(); 137 | } 138 | 139 | hostToIP(hosts.hostname,function(err,address){ 140 | if(address){ 141 | hosts.host = address; 142 | targetReceiver(hosts,ua); 143 | }else{ 144 | ua.end(); 145 | } 146 | }); 147 | } 148 | 149 | this.init = function(server){ 150 | server.on('connect',connection_handler); 151 | } 152 | } 153 | 154 | function hostToIP(host,cb){ 155 | dns.lookup(host,cb); 156 | } 157 | })(); 158 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-http-proxy", 3 | "version": "0.2.3", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "asn1": { 8 | "version": "0.1.11", 9 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", 10 | "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=" 11 | }, 12 | "assert-plus": { 13 | "version": "0.1.5", 14 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", 15 | "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=" 16 | }, 17 | "async": { 18 | "version": "0.9.2", 19 | "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", 20 | "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" 21 | }, 22 | "aws-sign2": { 23 | "version": "0.5.0", 24 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", 25 | "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=" 26 | }, 27 | "bl": { 28 | "version": "0.9.5", 29 | "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", 30 | "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", 31 | "requires": { 32 | "readable-stream": "~1.0.26" 33 | } 34 | }, 35 | "boom": { 36 | "version": "0.4.2", 37 | "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", 38 | "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", 39 | "requires": { 40 | "hoek": "0.9.x" 41 | } 42 | }, 43 | "bufferhelper": { 44 | "version": "0.2.0", 45 | "resolved": "https://registry.npmjs.org/bufferhelper/-/bufferhelper-0.2.0.tgz", 46 | "integrity": "sha1-7C842SU4dpzqKQFIeTXp4h2Bc7M=" 47 | }, 48 | "caseless": { 49 | "version": "0.8.0", 50 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.8.0.tgz", 51 | "integrity": "sha1-W8oogdQUN/VLJAfr40iIx7mtT30=" 52 | }, 53 | "combined-stream": { 54 | "version": "0.0.7", 55 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", 56 | "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", 57 | "requires": { 58 | "delayed-stream": "0.0.5" 59 | } 60 | }, 61 | "commander": { 62 | "version": "2.6.0", 63 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz", 64 | "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0=" 65 | }, 66 | "core-util-is": { 67 | "version": "1.0.2", 68 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 69 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 70 | }, 71 | "cryptiles": { 72 | "version": "0.2.2", 73 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", 74 | "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", 75 | "requires": { 76 | "boom": "0.4.x" 77 | } 78 | }, 79 | "ctype": { 80 | "version": "0.5.3", 81 | "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", 82 | "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=" 83 | }, 84 | "delayed-stream": { 85 | "version": "0.0.5", 86 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", 87 | "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=" 88 | }, 89 | "forever-agent": { 90 | "version": "0.5.2", 91 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", 92 | "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=" 93 | }, 94 | "form-data": { 95 | "version": "0.2.0", 96 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", 97 | "integrity": "sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY=", 98 | "requires": { 99 | "async": "~0.9.0", 100 | "combined-stream": "~0.0.4", 101 | "mime-types": "~2.0.3" 102 | }, 103 | "dependencies": { 104 | "mime-types": { 105 | "version": "2.0.14", 106 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", 107 | "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=", 108 | "requires": { 109 | "mime-db": "~1.12.0" 110 | } 111 | } 112 | } 113 | }, 114 | "hawk": { 115 | "version": "1.1.1", 116 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz", 117 | "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=", 118 | "requires": { 119 | "boom": "0.4.x", 120 | "cryptiles": "0.2.x", 121 | "hoek": "0.9.x", 122 | "sntp": "0.2.x" 123 | } 124 | }, 125 | "hoek": { 126 | "version": "0.9.1", 127 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", 128 | "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=" 129 | }, 130 | "http-signature": { 131 | "version": "0.10.1", 132 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", 133 | "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", 134 | "requires": { 135 | "asn1": "0.1.11", 136 | "assert-plus": "^0.1.5", 137 | "ctype": "0.5.3" 138 | } 139 | }, 140 | "inherits": { 141 | "version": "2.0.4", 142 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 143 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 144 | }, 145 | "isarray": { 146 | "version": "0.0.1", 147 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 148 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 149 | }, 150 | "json-stringify-safe": { 151 | "version": "5.0.1", 152 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 153 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 154 | }, 155 | "mime-db": { 156 | "version": "1.12.0", 157 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", 158 | "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=" 159 | }, 160 | "mime-types": { 161 | "version": "1.0.2", 162 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", 163 | "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=" 164 | }, 165 | "node-uuid": { 166 | "version": "1.4.8", 167 | "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", 168 | "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" 169 | }, 170 | "oauth-sign": { 171 | "version": "0.5.0", 172 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.5.0.tgz", 173 | "integrity": "sha1-12f1FpMlYg6rLgh+8MRy53PbZGE=" 174 | }, 175 | "pm": { 176 | "version": "2.2.5", 177 | "resolved": "https://registry.npmjs.org/pm/-/pm-2.2.5.tgz", 178 | "integrity": "sha1-IgJZn1m/trOID6naI0rdL0NLYK8=" 179 | }, 180 | "psl": { 181 | "version": "1.8.0", 182 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", 183 | "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" 184 | }, 185 | "punycode": { 186 | "version": "2.1.1", 187 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 188 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 189 | }, 190 | "qs": { 191 | "version": "2.3.3", 192 | "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", 193 | "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=" 194 | }, 195 | "readable-stream": { 196 | "version": "1.0.34", 197 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", 198 | "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", 199 | "requires": { 200 | "core-util-is": "~1.0.0", 201 | "inherits": "~2.0.1", 202 | "isarray": "0.0.1", 203 | "string_decoder": "~0.10.x" 204 | } 205 | }, 206 | "request": { 207 | "version": "2.51.0", 208 | "resolved": "https://registry.npmjs.org/request/-/request-2.51.0.tgz", 209 | "integrity": "sha1-NdALvswBLlX5B7G9ng29V3v+8m4=", 210 | "requires": { 211 | "aws-sign2": "~0.5.0", 212 | "bl": "~0.9.0", 213 | "caseless": "~0.8.0", 214 | "combined-stream": "~0.0.5", 215 | "forever-agent": "~0.5.0", 216 | "form-data": "~0.2.0", 217 | "hawk": "1.1.1", 218 | "http-signature": "~0.10.0", 219 | "json-stringify-safe": "~5.0.0", 220 | "mime-types": "~1.0.1", 221 | "node-uuid": "~1.4.0", 222 | "oauth-sign": "~0.5.0", 223 | "qs": "~2.3.1", 224 | "stringstream": "~0.0.4", 225 | "tough-cookie": ">=0.12.0", 226 | "tunnel-agent": "~0.4.0" 227 | } 228 | }, 229 | "sntp": { 230 | "version": "0.2.4", 231 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", 232 | "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", 233 | "requires": { 234 | "hoek": "0.9.x" 235 | } 236 | }, 237 | "string_decoder": { 238 | "version": "0.10.31", 239 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 240 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" 241 | }, 242 | "stringstream": { 243 | "version": "0.0.6", 244 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", 245 | "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==" 246 | }, 247 | "tough-cookie": { 248 | "version": "4.0.0", 249 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", 250 | "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", 251 | "requires": { 252 | "psl": "^1.1.33", 253 | "punycode": "^2.1.1", 254 | "universalify": "^0.1.2" 255 | } 256 | }, 257 | "tunnel-agent": { 258 | "version": "0.4.3", 259 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", 260 | "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" 261 | }, 262 | "universalify": { 263 | "version": "0.1.2", 264 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 265 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" 266 | } 267 | } 268 | } 269 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-http-proxy", 3 | "version": "0.2.4", 4 | "description": "a http(s) proxy server ", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node test.js" 8 | }, 9 | "engines": { 10 | "node": ">=0.10" 11 | }, 12 | "directories": { 13 | "bin": "./bin", 14 | "lib": "./lib", 15 | "test": "./test" 16 | }, 17 | "bin": { 18 | "nproxy": "./bin/node-http-proxy" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/wddqing/node-http-proxy.git" 23 | }, 24 | "dependencies": { 25 | "pm": "2.2.5", 26 | "bufferhelper": "0.2.0", 27 | "request": "2.51.0", 28 | "commander": "2.6.0" 29 | }, 30 | "devDependencies": { 31 | "pm": "latest", 32 | "bufferhelper": "latest", 33 | "request": "latest", 34 | "commander": "latest" 35 | }, 36 | "author": "wddqing", 37 | "license": "ISC", 38 | "bugs": { 39 | "url": "https://github.com/wddqing/node-http-proxy/issues" 40 | }, 41 | "homepage": "https://github.com/wddqing/node-http-proxy", 42 | "keywords": [ 43 | "node-http-proxy", 44 | "http-proxy", 45 | "proxy", 46 | "bufferhelper", 47 | "pm", 48 | "request", 49 | "commander" 50 | ] 51 | } 52 | --------------------------------------------------------------------------------