mirror of
https://github.com/bitinflow/server.git
synced 2026-03-13 13:35:53 +00:00
remove client components
* devDep localtunnel module for client * update readme for server info
This commit is contained in:
53
README.md
53
README.md
@@ -1,30 +1,10 @@
|
||||
# localtunnel [](http://travis-ci.org/shtylman/localtunnel) #
|
||||
# localtunnel-server [](http://travis-ci.org/shtylman/localtunnel-serer) #
|
||||
|
||||
localtunnel exposes your localhost to the world for easy testing and sharing! No need to mess with DNS or deploy just to have others test out your changes.
|
||||
|
||||
Great for working with browser testing tools like browserling or external api callback services like twilio which require a public url for callbacks.
|
||||
This repo is the server component. If you are just looking for the CLI localtunnel app, see (https://github.com/shtylman/localtunnel)
|
||||
|
||||
## installation ##
|
||||
|
||||
```
|
||||
npm install -g localtunnel
|
||||
```
|
||||
|
||||
This will install the localtunnel module globally and add the 'lt' client cli tool to your PATH.
|
||||
|
||||
## use ##
|
||||
|
||||
Super Easy! Assuming your local server is running on port 8000, just use the ```lt``` command to start the tunnel.
|
||||
|
||||
```
|
||||
lt --port 8000
|
||||
```
|
||||
|
||||
Thats it! It will connect to the tunnel server, setup the tunnel, and tell you what url to use for your testing. This url will remain active for the duration of your session; so feel free to share it with others for happy fun time!
|
||||
|
||||
You can restart your local server all you want, ```lt``` is smart enough to detect this and reconnect once it is back.
|
||||
|
||||
### custom server
|
||||
## overview ##
|
||||
|
||||
The default localtunnel client connects to the ```localtunnel.me``` server. You can however easily setup and run your own server. In order to run your own localtunnel server you must ensure that your server can meet the following requirements:
|
||||
|
||||
@@ -37,7 +17,7 @@ The above are important as the client will ask the server for a subdomain under
|
||||
|
||||
```shell
|
||||
// pick a place where the files will live
|
||||
git clone git://github.com/shtylman/localtunnel.git
|
||||
git clone git://github.com/shtylman/localtunnel-server.git
|
||||
cd localtunnel
|
||||
npm install
|
||||
|
||||
@@ -57,28 +37,3 @@ lt --host http://sub.example.tld:1234 --port 9000
|
||||
You will be assigned a url similar to ```qdci.sub.example.com:1234```
|
||||
|
||||
If your server is being a reverse proxy (i.e. nginx) and is able to listen on port 80, then you do not need the ```:1234``` part of the hostname for the ```lt``` client
|
||||
|
||||
## API ##
|
||||
|
||||
The localtunnel client is also usable through an API (test integration, automation, etc)
|
||||
|
||||
```javascript
|
||||
var lt_client = require('localtunnel').client;
|
||||
|
||||
var client = lt_client.connect({
|
||||
// the localtunnel server
|
||||
host: 'http://localtunnel.me',
|
||||
// your local application port
|
||||
port: 12345
|
||||
});
|
||||
|
||||
// when your are assigned a url
|
||||
client.on('url', function(url) {
|
||||
// you can now make http requests to the url
|
||||
// they will be proxied to your local server on port [12345]
|
||||
});
|
||||
|
||||
client.on('error', function(err) {
|
||||
// uh oh!
|
||||
});
|
||||
```
|
||||
|
||||
34
bin/client
34
bin/client
@@ -1,34 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
var lt_client = require(__dirname + '/../client');
|
||||
|
||||
var argv = require('optimist')
|
||||
.usage('Usage: $0 --port [num]')
|
||||
.demand(['port'])
|
||||
.options('host', {
|
||||
default: 'http://localtunnel.me',
|
||||
describe: 'upstream server providing forwarding'
|
||||
})
|
||||
.options('subdomain', {
|
||||
describe: 'request this subdomain'
|
||||
})
|
||||
.describe('port', 'internal http server port')
|
||||
.argv;
|
||||
|
||||
var opt = {
|
||||
host: argv.host,
|
||||
port: argv.port,
|
||||
subdomain: argv.subdomain,
|
||||
}
|
||||
|
||||
var client = lt_client.connect(opt);
|
||||
|
||||
// only emitted when the url changes
|
||||
client.on('url', function(url) {
|
||||
console.log('your url is: %s', url);
|
||||
});
|
||||
|
||||
client.on('error', function(err) {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
// vim: ft=javascript
|
||||
142
client.js
142
client.js
@@ -1,142 +0,0 @@
|
||||
// builtin
|
||||
var net = require('net');
|
||||
var url = require('url');
|
||||
var request = require('request');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
|
||||
// request upstream url and connection info
|
||||
var request_url = function(params, cb) {
|
||||
request(params, function(err, res, body) {
|
||||
if (err) {
|
||||
cb(err);
|
||||
}
|
||||
|
||||
cb(null, body);
|
||||
});
|
||||
};
|
||||
|
||||
var connect = function(opt) {
|
||||
var ev = new EventEmitter();
|
||||
|
||||
// local port
|
||||
var local_port = opt.port;
|
||||
|
||||
var base_uri = opt.host + '/';
|
||||
|
||||
// optionally override the upstream server
|
||||
var upstream = url.parse(opt.host);
|
||||
|
||||
// no subdomain at first, maybe use requested domain
|
||||
var assigned_domain = opt.subdomain;
|
||||
|
||||
// connect to upstream given connection parameters
|
||||
var tunnel = function (remote_host, remote_port) {
|
||||
|
||||
var remote_opt = {
|
||||
host: remote_host,
|
||||
port: remote_port
|
||||
};
|
||||
|
||||
var local_opt = {
|
||||
host: 'localhost',
|
||||
port: local_port
|
||||
};
|
||||
|
||||
var remote_attempts = 0;
|
||||
|
||||
(function conn(conn_had_error) {
|
||||
if (conn_had_error) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (++remote_attempts >= 3) {
|
||||
console.error('localtunnel server offline - try again');
|
||||
process.exit(-1);
|
||||
}
|
||||
|
||||
// connection to localtunnel server
|
||||
var remote = net.connect(remote_opt);
|
||||
|
||||
remote.once('error', function(err) {
|
||||
if (err.code !== 'ECONNREFUSED') {
|
||||
remote.emit('error', err);
|
||||
}
|
||||
|
||||
// retrying connection to local server
|
||||
setTimeout(conn, 1000);
|
||||
});
|
||||
|
||||
function recon_local() {
|
||||
remote.pause();
|
||||
remote_attempts = 0;
|
||||
|
||||
// connection to local http server
|
||||
var local = net.connect(local_opt);
|
||||
|
||||
local.once('error', function(err) {
|
||||
if (err.code !== 'ECONNREFUSED') {
|
||||
local.emit('error', err);
|
||||
}
|
||||
|
||||
// retrying connection to local server
|
||||
setTimeout(recon_local, 1000);
|
||||
});
|
||||
|
||||
local.once('connect', function() {
|
||||
remote.resume();
|
||||
remote.pipe(local).pipe(remote, {end: false});
|
||||
});
|
||||
|
||||
local.once('close', function(had_error) {
|
||||
if (had_error) {
|
||||
return;
|
||||
}
|
||||
recon_local();
|
||||
});
|
||||
}
|
||||
|
||||
remote.once('close', conn);
|
||||
remote.once('connect', recon_local);
|
||||
})();
|
||||
};
|
||||
|
||||
var params = {
|
||||
path: '/',
|
||||
json: true
|
||||
};
|
||||
|
||||
// where to quest
|
||||
params.uri = base_uri + ((assigned_domain) ? assigned_domain : '?new');
|
||||
|
||||
// get an id from lt server and setup forwarding tcp connections
|
||||
request_url(params, function(err, body) {
|
||||
|
||||
if (err) {
|
||||
ev.emit('error', new Error('tunnel server not available: %s, retry 1s', err.message));
|
||||
|
||||
// retry interval for id request
|
||||
return setTimeout(function() {
|
||||
connect_proxy(opt);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// our assigned hostname and tcp port
|
||||
var port = body.port;
|
||||
var host = upstream.hostname;
|
||||
|
||||
// store the id so we can try to get the same one
|
||||
assigned_domain = body.id;
|
||||
|
||||
var max_conn = body.max_conn_count || 1;
|
||||
for (var count = 0 ; count < max_conn ; ++count) {
|
||||
tunnel(host, port);
|
||||
}
|
||||
|
||||
ev.emit('url', body.url);
|
||||
});
|
||||
|
||||
return ev;
|
||||
};
|
||||
|
||||
module.exports.connect = connect;
|
||||
|
||||
2
index.js
2
index.js
@@ -1,2 +0,0 @@
|
||||
module.exports.client = require('./client');
|
||||
module.exports.server = require('./server');
|
||||
20
package.json
20
package.json
@@ -1,31 +1,25 @@
|
||||
{
|
||||
"author": "Roman Shtylman <shtylman@gmail.com>",
|
||||
"name": "localtunnel",
|
||||
"name": "localtunnel-server",
|
||||
"description": "expose localhost to the world",
|
||||
"version": "0.0.4",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/shtylman/localtunnel.git"
|
||||
"url": "git://github.com/shtylman/localtunnel-server.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"request": "2.11.4",
|
||||
"book": "1.2.0",
|
||||
"optimist": "0.3.4",
|
||||
"http-raw": "1.1.0"
|
||||
"http-raw": "1.1.0",
|
||||
"debug": "0.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "1.6.0"
|
||||
},
|
||||
"optionalDependencies": {},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
"mocha": "1.6.0",
|
||||
"localtunnel": "0.0.4"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha --ui qunit -- test",
|
||||
"start": "./bin/server"
|
||||
},
|
||||
"bin": {
|
||||
"lt": "./bin/client"
|
||||
},
|
||||
"main": "./index.js"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ var http = require('http');
|
||||
var url = require('url');
|
||||
var assert = require('assert');
|
||||
|
||||
var localtunnel_server = require('../').server();
|
||||
var localtunnel_client = require('../').client;
|
||||
var localtunnel_server = require('../server')();
|
||||
var localtunnel_client = require('localtunnel').client;
|
||||
|
||||
test('setup localtunnel server', function(done) {
|
||||
localtunnel_server.listen(3000, function() {
|
||||
|
||||
@@ -2,11 +2,11 @@ var http = require('http');
|
||||
var url = require('url');
|
||||
var assert = require('assert');
|
||||
|
||||
var localtunnel_server = require('../').server({
|
||||
var localtunnel_server = require('../server')({
|
||||
max_tcp_sockets: 1
|
||||
});
|
||||
|
||||
var localtunnel_client = require('../').client;
|
||||
var localtunnel_client = require('localtunnel').client;
|
||||
|
||||
var server;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user