rename to catalyst-proxy, add a CLI utility
This commit is contained in:
parent
0e5ffe367d
commit
9a9bd308ce
7 changed files with 86 additions and 26 deletions
29
README.md
29
README.md
|
|
@ -1,3 +1,28 @@
|
|||
multipart-proxy
|
||||
catalyst-proxy
|
||||
==============
|
||||
A proxy that accelerates requests via multipart downloading. Very much WIP.
|
||||
A proxy that silently accelerates requests via multipart downloading. Officially the best thing ever.
|
||||
|
||||
`catalyst-proxy` establishes multiples connections to download a single resource from a web server, potentially increasing the download speed.
|
||||
|
||||
Only supports "streaming" acceleration for now: resources are cut into parts of equal length (`--partSize` CLI option) that are downloaded concurrently (`--threads` CLI option) and served sequentially. This behavior differs from most download managers and allows to consume the resource while downloading it.
|
||||
|
||||
Use-cases
|
||||
---------
|
||||
* Speed up video streaming websites, such as YouTube.
|
||||
* Speed up software and game downloaders/installers.
|
||||
* Speed up everything.
|
||||
|
||||
Installation
|
||||
------------
|
||||
You need to have Node.JS >= 0.10.0 installed on your system.
|
||||
```$ npm install -g catalyst-proxy```
|
||||
|
||||
To update:
|
||||
```$ npm update -g catalyst-proxy```
|
||||
|
||||
Usage
|
||||
-----
|
||||
```$ catalyst start``` to boot up the proxy. Simply add the printed address and port as an HTTP proxy in your system settings and you're set.
|
||||
|
||||
```$ catalyst start -h``` to list all available options.
|
||||
|
||||
|
|
|
|||
2
bin/catalyst.js
Executable file
2
bin/catalyst.js
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env node
|
||||
require(__dirname + '/../lib/cli');
|
||||
11
package.json
11
package.json
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "multipart-proxy",
|
||||
"name": "catalyst-proxy",
|
||||
"description": "A proxy that accelerates requests via multipart downloading",
|
||||
"author": "Alexandre Kirszenberg <a.kirszenberg@gmail.com>",
|
||||
"version": "0.1.0",
|
||||
|
|
@ -12,7 +12,11 @@
|
|||
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:morhaus/multipart-proxy.git"
|
||||
"url": "git@github.com:morhaus/catalyst-proxy.git"
|
||||
},
|
||||
|
||||
"bin": {
|
||||
"catalyst": "./bin/catalyst.js"
|
||||
},
|
||||
|
||||
"scripts": {
|
||||
|
|
@ -26,9 +30,8 @@
|
|||
"engineStrict": true,
|
||||
|
||||
"dependencies": {
|
||||
"commander": "2.0.0",
|
||||
"commander": "2.*",
|
||||
"lodash": "*",
|
||||
"async": "*",
|
||||
"multisource-stream": "0.0.*",
|
||||
"tmpl-log": "0.0.*"
|
||||
},
|
||||
|
|
|
|||
33
src/cli.coffee
Normal file
33
src/cli.coffee
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
http = require 'http'
|
||||
|
||||
program = require 'commander'
|
||||
Logger = require 'tmpl-log'
|
||||
|
||||
Proxy = require './proxy'
|
||||
|
||||
logr = new Logger
|
||||
|
||||
program
|
||||
.version('0.1.0')
|
||||
|
||||
program
|
||||
.command('start')
|
||||
.option('-p, --port <p>', 'port on which to listen', Number, 8080)
|
||||
.option('-H, --host <h>', 'host on which to start the proxy', String, 'localhost')
|
||||
.option('-t, --threads <t>', 'max concurrent threads', Number, 12)
|
||||
.option('-s, --partSize <p>', 'thread part size', Number, 1024 * 1024 * 2)
|
||||
.option('-l, --contentLength <l>', 'min content length for threaded downloading', Number, 1024 * 1024 * 4)
|
||||
.action (args..., { port, host, threads, partSize, contentLength }) ->
|
||||
proxy = new Proxy { threads, partSize, contentLength }
|
||||
proxy.on 'error', (e) ->
|
||||
if e.syscall is 'listen'
|
||||
switch e.code
|
||||
when 'EADDRNOTAVAIL' then logr.log "<underline><red>Error:</></> address or port not available (<bold>http://<underline>#{host}</>:#{port}</>)"
|
||||
when 'EACCES' then logr.log "<underline><red>Error:</></> reserved address or port (<bold>http://<underline>#{host}</>:#{port}</>)"
|
||||
throw e
|
||||
proxy.listen port, host, ->
|
||||
logr.log """
|
||||
Proxy started on <bold>http://<underline>#{host}</>:#{port}</>. Press CTRL+C to stop it.
|
||||
"""
|
||||
|
||||
program.parse process.argv
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
http = require 'http'
|
||||
Proxy = require './proxy'
|
||||
|
||||
http.globalAgent.maxSockets = Infinity
|
||||
|
||||
new Proxy 8080
|
||||
|
|
@ -1,34 +1,34 @@
|
|||
http = require 'http'
|
||||
url = require 'url'
|
||||
{ EventEmitter } = require 'events'
|
||||
|
||||
_ = require 'lodash'
|
||||
|
||||
Request = require './request'
|
||||
|
||||
module.exports = class Proxy
|
||||
constructor: (listenPort, listenHost, opts = {}) ->
|
||||
if typeof listenHost is 'object'
|
||||
opts = listenHost
|
||||
listenHost = undefined
|
||||
module.exports = class Proxy extends EventEmitter
|
||||
constructor: (opts = {}) ->
|
||||
super()
|
||||
|
||||
@opts = _.clone opts
|
||||
_.defaults @opts,
|
||||
maxConcurrent: 12
|
||||
threads: 12
|
||||
partSize: 1024 * 1024 / 4
|
||||
minContentLength: 1024 * 1024
|
||||
contentLength: 1024 * 1024
|
||||
|
||||
http.createServer()
|
||||
.on('request', @request)
|
||||
.listen(listenPort, listenHost)
|
||||
@server = http.createServer()
|
||||
@server.on 'request', @request
|
||||
@server.on 'error', (e) =>
|
||||
@emit 'error', e
|
||||
|
||||
_isDownloadable: (res) ->
|
||||
res.statusCode in [200, 206] and (parseInt res.headers['content-length']) >= @opts.minContentLength
|
||||
res.statusCode in [200, 206] and (parseInt res.headers['content-length']) >= @opts.contentLength
|
||||
|
||||
request: (clientReq, clientRes) =>
|
||||
reqOpts = url.parse clientReq.url
|
||||
reqOpts.method = clientReq.method
|
||||
reqOpts.headers = clientReq.headers
|
||||
reqOpts.agent = new http.Agent maxSockets: @opts.maxConcurrent
|
||||
reqOpts.agent = new http.Agent maxSockets: @opts.threads
|
||||
|
||||
# Create new request
|
||||
request = new Request reqOpts, @opts
|
||||
|
|
@ -48,3 +48,6 @@ module.exports = class Proxy
|
|||
# Stop the request whether or not it has completed
|
||||
clientRes.on 'close', ->
|
||||
request.stop()
|
||||
|
||||
listen: (port, host, callback) ->
|
||||
@server.listen port, host, callback
|
||||
|
|
|
|||
|
|
@ -224,8 +224,8 @@ module.exports = class Request extends Duplex
|
|||
|
||||
# Fills the running thread pool
|
||||
_fill: ->
|
||||
console.log "FILL #{@runningPool.length}/#{@opts.maxConcurrent}, #{@offset}/#{@range[1]}, #{@pool.indexOf @runningPool[0]}"
|
||||
if @runningPool.length < @opts.maxConcurrent and @offset isnt @range[1]
|
||||
console.log "FILL #{@runningPool.length}/#{@opts.threads}, #{@offset}/#{@range[1]}, #{@pool.indexOf @runningPool[0]}"
|
||||
if @runningPool.length < @opts.threads and @offset isnt @range[1]
|
||||
# Calculate correct thread length
|
||||
length = @range[1] - @offset
|
||||
length = @opts.partSize if length > @opts.partSize
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue