├── .npmignore ├── README.md ├── src ├── utils.coffee ├── middleware │ ├── echo.coffee │ ├── bufferParser.coffee │ └── logger.coffee ├── connect_tcp.coffee └── proto.coffee ├── .gitignore ├── lib ├── utils.js ├── middleware │ ├── echo.js │ ├── bufferParser.js │ └── logger.js ├── connect_tcp.js └── proto.js ├── examples ├── echo.coffee ├── echo.js ├── session.coffee ├── session.js ├── 1337.coffee └── 1337.js ├── package.json └── Cakefile /.npmignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *# 3 | .#* 4 | /src 5 | /Cakefile 6 | .git* 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | connect-tcp 2 | =========== 3 | 4 | TCP version of SenchaLabs's Connect middleware layer for Node.js 5 | -------------------------------------------------------------------------------- /src/utils.coffee: -------------------------------------------------------------------------------- 1 | exports.merge = (a, b) -> 2 | if a and b 3 | for key of b 4 | a[key] = b[key] 5 | return a -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | 14 | npm-debug.log 15 | 16 | /node_modules 17 | 18 | *~ 19 | .#* 20 | *# 21 | -------------------------------------------------------------------------------- /src/middleware/echo.coffee: -------------------------------------------------------------------------------- 1 | debug = require('debug') 'connect-tcp:middleware:echo' 2 | 3 | echo = exports = module.exports = -> 4 | middleware = (req, res, next) -> 5 | debug "write #{req.buffer.length} bytes" 6 | res.write req.buffer 7 | do next 8 | return middleware 9 | -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | (function() { 3 | exports.merge = function(a, b) { 4 | var key; 5 | if (a && b) { 6 | for (key in b) { 7 | a[key] = b[key]; 8 | } 9 | } 10 | return a; 11 | }; 12 | 13 | }).call(this); 14 | -------------------------------------------------------------------------------- /examples/echo.coffee: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env coffee 2 | # 3 | # coffee ./echo.coffee 4 | # nc localhost 3045 5 | 6 | connect_tcp = require '..' 7 | 8 | server = connect_tcp.createServer() 9 | 10 | server.use connect_tcp.echo() 11 | 12 | server.listen 3045, -> console.log "listening on port 3045" 13 | -------------------------------------------------------------------------------- /examples/echo.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | (function() { 3 | var connect_tcp, server; 4 | 5 | connect_tcp = require('..'); 6 | 7 | server = connect_tcp.createServer(); 8 | 9 | server.use(connect_tcp.echo()); 10 | 11 | server.listen(3045, function() { 12 | return console.log("listening on port 3045"); 13 | }); 14 | 15 | }).call(this); 16 | -------------------------------------------------------------------------------- /examples/session.coffee: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env coffee 2 | # 3 | # coffee ./session.coffee 4 | # nc localhost 3046 5 | 6 | connect_tcp = require '..' 7 | 8 | server = connect_tcp.createServer() 9 | 10 | server.use (req, res) -> 11 | req.session.line ?= 0 12 | req.session.line++ 13 | res.send "line = #{req.session.line}" 14 | 15 | server.listen 3046, -> console.log "listening on port 3046" 16 | -------------------------------------------------------------------------------- /src/middleware/bufferParser.coffee: -------------------------------------------------------------------------------- 1 | debug = require('debug') 'connect-tcp:middleware:bufferParser' 2 | 3 | bufferParser = exports = module.exports = -> 4 | middleware = (req, res, next) -> 5 | req.data = bufferParser.bufferToString req.buffer 6 | do next 7 | return middleware 8 | 9 | bufferParser.bufferToString = (buffer) -> 10 | string = buffer.toString() 11 | string = string.replace /^\s+|\s+$/g, "" 12 | return string 13 | -------------------------------------------------------------------------------- /lib/middleware/echo.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | (function() { 3 | var debug, echo, exports; 4 | 5 | debug = require('debug')('connect-tcp:middleware:echo'); 6 | 7 | echo = exports = module.exports = function() { 8 | var middleware; 9 | middleware = function(req, res, next) { 10 | debug("write " + req.buffer.length + " bytes"); 11 | res.write(req.buffer); 12 | return next(); 13 | }; 14 | return middleware; 15 | }; 16 | 17 | }).call(this); 18 | -------------------------------------------------------------------------------- /examples/session.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | (function() { 3 | var connect_tcp, server; 4 | 5 | connect_tcp = require('..'); 6 | 7 | server = connect_tcp.createServer(); 8 | 9 | server.use(function(req, res) { 10 | var _base; 11 | if ((_base = req.session).line == null) { 12 | _base.line = 0; 13 | } 14 | req.session.line++; 15 | return res.send("line = " + req.session.line); 16 | }); 17 | 18 | server.listen(3046, function() { 19 | return console.log("listening on port 3046"); 20 | }); 21 | 22 | }).call(this); 23 | -------------------------------------------------------------------------------- /lib/middleware/bufferParser.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | (function() { 3 | var bufferParser, debug, exports; 4 | 5 | debug = require('debug')('connect-tcp:middleware:bufferParser'); 6 | 7 | bufferParser = exports = module.exports = function() { 8 | var middleware; 9 | middleware = function(req, res, next) { 10 | req.data = bufferParser.bufferToString(req.buffer); 11 | return next(); 12 | }; 13 | return middleware; 14 | }; 15 | 16 | bufferParser.bufferToString = function(buffer) { 17 | var string; 18 | string = buffer.toString(); 19 | string = string.replace(/^\s+|\s+$/g, ""); 20 | return string; 21 | }; 22 | 23 | }).call(this); 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "connect-tcp", 3 | "version": "0.2.5", 4 | "description": "TCP version of SenchaLabs's Connect middleware layer for Node.js", 5 | "main": "lib/connect_tcp.js", 6 | "directories": { 7 | "example": "examples" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "dependencies": { 13 | "debug": "*" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git://github.com/moul/connect-tcp.git" 18 | }, 19 | "keywords": [ 20 | "middleware", 21 | "connect", 22 | "tcp", 23 | "connect-tcp" 24 | ], 25 | "author": "Manfred Touron ", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/moul/connect-tcp/issues" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/middleware/logger.coffee: -------------------------------------------------------------------------------- 1 | debug = require('debug') 'connect-tcp:middleware:logger' 2 | 3 | logger = exports = module.exports = (options) -> 4 | if 'object' is typeof options 5 | options ?= {} 6 | else if options 7 | options = format: options 8 | else 9 | options = {} 10 | 11 | logger = (req, res, next) -> 12 | debug "Message from logger" 13 | do next 14 | 15 | return logger 16 | 17 | module.exports.sock_logger = (options) -> 18 | sock_logger = (connection, next) -> 19 | debug "Message from sock_logger" 20 | connection.on 'end', -> debug 'message from sock_logger on end' 21 | connection.on 'data', -> debug 'message from sock_logger on data' 22 | connection.on 'error', -> debug 'message from sock_logger on error' 23 | do next 24 | 25 | return sock_logger 26 | -------------------------------------------------------------------------------- /Cakefile: -------------------------------------------------------------------------------- 1 | {spawn, exec} = require 'child_process' 2 | 3 | call = (command, args = [], fn = null) -> 4 | exec "#{command} #{args.join(' ')}", (err, stdout, stderr) -> 5 | if err? 6 | console.error "Error :" 7 | return console.dir err 8 | fn err if fn 9 | 10 | system = (command, args) -> 11 | spawn command, args, stdio: "inherit" 12 | 13 | build = (fn = null) -> 14 | call 'coffee', ['-c', '-o', 'lib', 'src'] 15 | call 'coffee', ['-c', '-o', 'examples', 'examples'] 16 | 17 | watch = (fn = null) -> 18 | system 'coffee', ['-w', '-c', '-o', 'lib', 'src'] 19 | system 'coffee', ['-w', '-c', '-o', 'examples', 'examples'] 20 | 21 | task 'watch', 'continually build the JavaScript code', -> 22 | watch -> console.log "Done !" 23 | 24 | task 'build', 'build the JavaScript code', -> 25 | build -> console.log "Done !" 26 | -------------------------------------------------------------------------------- /examples/1337.coffee: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env coffee 2 | # 3 | # DEBUG='*' coffee ./1337.coffee 4 | # nc localhost 3044 5 | 6 | debug = require('debug') 'connect-tcp:examples:1337' 7 | connect_tcp = require '..' 8 | 9 | server = connect_tcp.createServer() 10 | server.use connect_tcp.logger() 11 | server.sock_use connect_tcp.logger.sock_logger() 12 | 13 | server.use connect_tcp.bufferParser() 14 | 15 | server.use (req, res, next) -> 16 | debug 'uppercasing data' 17 | req.data = req.data.toUpperCase() 18 | do next 19 | 20 | server.use (req, res, next) -> 21 | debug '1337ing data' 22 | translations = 23 | 0: /[oO]/ 24 | 1: /[lL]/ 25 | 2: /[zZ]/ 26 | 3: /[eE]/ 27 | 4: /[aA]/ 28 | 5: /[sS]/ 29 | 6: /[gG]/ 30 | 7: /[tT]/ 31 | 8: /[bB]/ 32 | for translation, exp of translations 33 | req.data = req.data.replace exp, translation.toString() 34 | do next 35 | 36 | server.use (req, res, next) -> 37 | debug 'reversing letters' 38 | req.data = req.data.split('').reverse().join('') 39 | do next 40 | 41 | server.use (req, res, next) -> 42 | debug 'sending back data', req.data 43 | res.send req.data 44 | do next 45 | 46 | server.listen 3044, -> debug "listening on port 3044" 47 | -------------------------------------------------------------------------------- /lib/middleware/logger.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | (function() { 3 | var debug, exports, logger; 4 | 5 | debug = require('debug')('connect-tcp:middleware:logger'); 6 | 7 | logger = exports = module.exports = function(options) { 8 | if ('object' === typeof options) { 9 | if (options == null) { 10 | options = {}; 11 | } 12 | } else if (options) { 13 | options = { 14 | format: options 15 | }; 16 | } else { 17 | options = {}; 18 | } 19 | logger = function(req, res, next) { 20 | debug("Message from logger"); 21 | return next(); 22 | }; 23 | return logger; 24 | }; 25 | 26 | module.exports.sock_logger = function(options) { 27 | var sock_logger; 28 | sock_logger = function(connection, next) { 29 | debug("Message from sock_logger"); 30 | connection.on('end', function() { 31 | return debug('message from sock_logger on end'); 32 | }); 33 | connection.on('data', function() { 34 | return debug('message from sock_logger on data'); 35 | }); 36 | connection.on('error', function() { 37 | return debug('message from sock_logger on error'); 38 | }); 39 | return next(); 40 | }; 41 | return sock_logger; 42 | }; 43 | 44 | }).call(this); 45 | -------------------------------------------------------------------------------- /src/connect_tcp.coffee: -------------------------------------------------------------------------------- 1 | {EventEmitter} = require 'events' 2 | proto = require './proto' 3 | utils = require './utils' 4 | fs = require 'fs' 5 | path = require 'path' 6 | basename = path.basename 7 | debug = require('debug') 'connect-tcp:main' 8 | 9 | createServer = -> 10 | debug 'createServer' 11 | app = (socket, next) -> 12 | app.sock_handle socket, next 13 | socket.session ?= {} 14 | socket.on 'data', (buffer) -> 15 | req = 16 | buffer: buffer 17 | #data: buffer.toString() 18 | socket: socket 19 | session: socket.session 20 | res = 21 | send: (data) -> socket.write data + '\n' 22 | write: (data) -> socket.write data 23 | app.data_handle req, res, next 24 | utils.merge app, proto 25 | utils.merge app, EventEmitter.prototype 26 | app.sock_stack = [] 27 | app.data_stack = [] 28 | app.use arg for arg of arguments 29 | return app 30 | 31 | exports = module.exports = createServer 32 | exports.version = '0.2.0' 33 | exports.middleware = {} 34 | exports.utils = utils 35 | createServer.createServer = createServer 36 | 37 | fs.readdirSync("#{__dirname}/middleware").forEach (filename) -> 38 | return unless /\.js$/.test(filename) 39 | name = basename filename, '.js' 40 | load = -> require "./middleware/#{name}" 41 | exports.middleware.__defineGetter__ name, load 42 | exports.__defineGetter__ name, load 43 | -------------------------------------------------------------------------------- /examples/1337.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | (function() { 3 | var connect_tcp, debug, server; 4 | 5 | debug = require('debug')('connect-tcp:examples:1337'); 6 | 7 | connect_tcp = require('..'); 8 | 9 | server = connect_tcp.createServer(); 10 | 11 | server.use(connect_tcp.logger()); 12 | 13 | server.sock_use(connect_tcp.logger.sock_logger()); 14 | 15 | server.use(connect_tcp.bufferParser()); 16 | 17 | server.use(function(req, res, next) { 18 | debug('uppercasing data'); 19 | req.data = req.data.toUpperCase(); 20 | return next(); 21 | }); 22 | 23 | server.use(function(req, res, next) { 24 | var exp, translation, translations; 25 | debug('1337ing data'); 26 | translations = { 27 | 0: /[oO]/, 28 | 1: /[lL]/, 29 | 2: /[zZ]/, 30 | 3: /[eE]/, 31 | 4: /[aA]/, 32 | 5: /[sS]/, 33 | 6: /[gG]/, 34 | 7: /[tT]/, 35 | 8: /[bB]/ 36 | }; 37 | for (translation in translations) { 38 | exp = translations[translation]; 39 | req.data = req.data.replace(exp, translation.toString()); 40 | } 41 | return next(); 42 | }); 43 | 44 | server.use(function(req, res, next) { 45 | debug('reversing letters'); 46 | req.data = req.data.split('').reverse().join(''); 47 | return next(); 48 | }); 49 | 50 | server.use(function(req, res, next) { 51 | debug('sending back data', req.data); 52 | res.send(req.data); 53 | return next(); 54 | }); 55 | 56 | server.listen(3044, function() { 57 | return debug("listening on port 3044"); 58 | }); 59 | 60 | }).call(this); 61 | -------------------------------------------------------------------------------- /src/proto.coffee: -------------------------------------------------------------------------------- 1 | utils = require './utils' 2 | debug = require('debug') 'connect-tcp:proto' 3 | net = require 'net' 4 | 5 | exports = module.exports = app = {} 6 | 7 | app.use = app.data_use = (fn) -> 8 | debug "data_use %s", fn.name || 'anonymous' 9 | @data_stack.push handle: fn 10 | return this 11 | 12 | app.handle = app.data_handle = (req, res, out) -> 13 | data_stack = @data_stack 14 | index = 0 15 | 16 | next = (err) -> 17 | layer = data_stack[index++] 18 | 19 | unless layer 20 | return out err if out 21 | # TODO: default error handling 22 | #socket.end() 23 | return 24 | 25 | try 26 | arity = layer.handle.length 27 | if err 28 | if arity is 4 29 | layer.handle err, req, res, next 30 | else 31 | next err 32 | else if arity < 4 33 | layer.handle req, res, next 34 | else 35 | do next 36 | catch e 37 | next e 38 | 39 | do next 40 | 41 | app.sock_use = (fn) -> 42 | debug "sock_use %s", fn.name || 'anonymous' 43 | @sock_stack.push handle: fn 44 | return this 45 | 46 | app.sock_handle = (connection, out) -> 47 | sock_stack = @sock_stack 48 | index = 0 49 | 50 | next = (err) -> 51 | layer = sock_stack[index++] 52 | 53 | unless layer 54 | return out err if out 55 | # TODO: default error handling 56 | #connection.end() 57 | return 58 | 59 | try 60 | arity = layer.handle.length 61 | if err 62 | if arity is 3 63 | layer.handle err, connection, next 64 | else 65 | next err 66 | else if arity < 3 67 | layer.handle connection, next 68 | else 69 | do next 70 | catch e 71 | next e 72 | 73 | do next 74 | 75 | app.listen = -> 76 | server = net.createServer this 77 | server.listen.apply server, arguments 78 | -------------------------------------------------------------------------------- /lib/connect_tcp.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | (function() { 3 | var EventEmitter, basename, createServer, debug, exports, fs, path, proto, utils; 4 | 5 | EventEmitter = require('events').EventEmitter; 6 | 7 | proto = require('./proto'); 8 | 9 | utils = require('./utils'); 10 | 11 | fs = require('fs'); 12 | 13 | path = require('path'); 14 | 15 | basename = path.basename; 16 | 17 | debug = require('debug')('connect-tcp:main'); 18 | 19 | createServer = function() { 20 | var app, arg; 21 | debug('createServer'); 22 | app = function(socket, next) { 23 | app.sock_handle(socket, next); 24 | if (socket.session == null) { 25 | socket.session = {}; 26 | } 27 | return socket.on('data', function(buffer) { 28 | var req, res; 29 | req = { 30 | buffer: buffer, 31 | socket: socket, 32 | session: socket.session 33 | }; 34 | res = { 35 | send: function(data) { 36 | return socket.write(data + '\n'); 37 | }, 38 | write: function(data) { 39 | return socket.write(data); 40 | } 41 | }; 42 | return app.data_handle(req, res, next); 43 | }); 44 | }; 45 | utils.merge(app, proto); 46 | utils.merge(app, EventEmitter.prototype); 47 | app.sock_stack = []; 48 | app.data_stack = []; 49 | for (arg in arguments) { 50 | app.use(arg); 51 | } 52 | return app; 53 | }; 54 | 55 | exports = module.exports = createServer; 56 | 57 | exports.version = '0.2.0'; 58 | 59 | exports.middleware = {}; 60 | 61 | exports.utils = utils; 62 | 63 | createServer.createServer = createServer; 64 | 65 | fs.readdirSync("" + __dirname + "/middleware").forEach(function(filename) { 66 | var load, name; 67 | if (!/\.js$/.test(filename)) { 68 | return; 69 | } 70 | name = basename(filename, '.js'); 71 | load = function() { 72 | return require("./middleware/" + name); 73 | }; 74 | exports.middleware.__defineGetter__(name, load); 75 | return exports.__defineGetter__(name, load); 76 | }); 77 | 78 | }).call(this); 79 | -------------------------------------------------------------------------------- /lib/proto.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | (function() { 3 | var app, debug, exports, net, utils; 4 | 5 | utils = require('./utils'); 6 | 7 | debug = require('debug')('connect-tcp:proto'); 8 | 9 | net = require('net'); 10 | 11 | exports = module.exports = app = {}; 12 | 13 | app.use = app.data_use = function(fn) { 14 | debug("data_use %s", fn.name || 'anonymous'); 15 | this.data_stack.push({ 16 | handle: fn 17 | }); 18 | return this; 19 | }; 20 | 21 | app.handle = app.data_handle = function(req, res, out) { 22 | var data_stack, index, next; 23 | data_stack = this.data_stack; 24 | index = 0; 25 | next = function(err) { 26 | var arity, e, layer; 27 | layer = data_stack[index++]; 28 | if (!layer) { 29 | if (out) { 30 | return out(err); 31 | } 32 | return; 33 | } 34 | try { 35 | arity = layer.handle.length; 36 | if (err) { 37 | if (arity === 4) { 38 | return layer.handle(err, req, res, next); 39 | } else { 40 | return next(err); 41 | } 42 | } else if (arity < 4) { 43 | return layer.handle(req, res, next); 44 | } else { 45 | return next(); 46 | } 47 | } catch (_error) { 48 | e = _error; 49 | return next(e); 50 | } 51 | }; 52 | return next(); 53 | }; 54 | 55 | app.sock_use = function(fn) { 56 | debug("sock_use %s", fn.name || 'anonymous'); 57 | this.sock_stack.push({ 58 | handle: fn 59 | }); 60 | return this; 61 | }; 62 | 63 | app.sock_handle = function(connection, out) { 64 | var index, next, sock_stack; 65 | sock_stack = this.sock_stack; 66 | index = 0; 67 | next = function(err) { 68 | var arity, e, layer; 69 | layer = sock_stack[index++]; 70 | if (!layer) { 71 | if (out) { 72 | return out(err); 73 | } 74 | return; 75 | } 76 | try { 77 | arity = layer.handle.length; 78 | if (err) { 79 | if (arity === 3) { 80 | return layer.handle(err, connection, next); 81 | } else { 82 | return next(err); 83 | } 84 | } else if (arity < 3) { 85 | return layer.handle(connection, next); 86 | } else { 87 | return next(); 88 | } 89 | } catch (_error) { 90 | e = _error; 91 | return next(e); 92 | } 93 | }; 94 | return next(); 95 | }; 96 | 97 | app.listen = function() { 98 | var server; 99 | server = net.createServer(this); 100 | return server.listen.apply(server, arguments); 101 | }; 102 | 103 | }).call(this); 104 | --------------------------------------------------------------------------------