Skip to content
Browse files

allow attachments to be an http endpoint

  • Loading branch information...
1 parent ee8e069 commit f12ff711bfe8fb50eb146aa33ca6a8bfdb36a3dd @maxogden committed Mar 11, 2012
Showing with 9,798 additions and 19 deletions.
  1. +17 −8 index.js
  2. +14 −10 node_modules/filed/main.js
  3. +1 −1 node_modules/filed/package.json
  4. +3 −0 node_modules/socket.io/.npmignore
  5. +7 −0 node_modules/socket.io/.travis.yml
  6. +218 −0 node_modules/socket.io/History.md
  7. +31 −0 node_modules/socket.io/Makefile
  8. +343 −0 node_modules/socket.io/Readme.md
  9. +64 −0 node_modules/socket.io/benchmarks/decode.bench.js
  10. +90 −0 node_modules/socket.io/benchmarks/encode.bench.js
  11. +55 −0 node_modules/socket.io/benchmarks/runner.js
  12. +80 −0 node_modules/socket.io/examples/chat/app.js
  13. +83 −0 node_modules/socket.io/examples/chat/index.jade
  14. +11 −0 node_modules/socket.io/examples/chat/package.json
  15. +96 −0 node_modules/socket.io/examples/chat/public/stylesheets/mixins.styl
  16. +188 −0 node_modules/socket.io/examples/chat/public/stylesheets/style.css
  17. +118 −0 node_modules/socket.io/examples/chat/public/stylesheets/style.styl
  18. +74 −0 node_modules/socket.io/examples/irc-output/app.js
  19. +28 −0 node_modules/socket.io/examples/irc-output/index.jade
  20. +164 −0 node_modules/socket.io/examples/irc-output/irc.js
  21. +10 −0 node_modules/socket.io/examples/irc-output/package.json
  22. +69 −0 node_modules/socket.io/examples/irc-output/public/stylesheets/style.styl
  23. +8 −0 node_modules/socket.io/index.js
  24. +97 −0 node_modules/socket.io/lib/logger.js
  25. +977 −0 node_modules/socket.io/lib/manager.js
  26. +355 −0 node_modules/socket.io/lib/namespace.js
  27. +249 −0 node_modules/socket.io/lib/parser.js
  28. +136 −0 node_modules/socket.io/lib/socket.io.js
  29. +362 −0 node_modules/socket.io/lib/socket.js
  30. +395 −0 node_modules/socket.io/lib/static.js
  31. +98 −0 node_modules/socket.io/lib/store.js
  32. +143 −0 node_modules/socket.io/lib/stores/memory.js
  33. +269 −0 node_modules/socket.io/lib/stores/redis.js
  34. +534 −0 node_modules/socket.io/lib/transport.js
  35. +106 −0 node_modules/socket.io/lib/transports/flashsocket.js
  36. +82 −0 node_modules/socket.io/lib/transports/htmlfile.js
  37. +135 −0 node_modules/socket.io/lib/transports/http-polling.js
  38. +118 −0 node_modules/socket.io/lib/transports/http.js
  39. +12 −0 node_modules/socket.io/lib/transports/index.js
  40. +96 −0 node_modules/socket.io/lib/transports/jsonp-polling.js
  41. +36 −0 node_modules/socket.io/lib/transports/websocket.js
  42. +360 −0 node_modules/socket.io/lib/transports/websocket/default.js
  43. +622 −0 node_modules/socket.io/lib/transports/websocket/hybi-07-12.js
  44. +623 −0 node_modules/socket.io/lib/transports/websocket/hybi-16.js
  45. +11 −0 node_modules/socket.io/lib/transports/websocket/index.js
  46. +69 −0 node_modules/socket.io/lib/transports/xhr-polling.js
  47. +50 −0 node_modules/socket.io/lib/util.js
  48. +1 −0 node_modules/socket.io/node_modules/policyfile/.npmignore
  49. +19 −0 node_modules/socket.io/node_modules/policyfile/LICENSE
  50. +7 −0 node_modules/socket.io/node_modules/policyfile/Makefile
  51. +98 −0 node_modules/socket.io/node_modules/policyfile/README.md
  52. +375 −0 node_modules/socket.io/node_modules/policyfile/doc/index.html
  53. +8 −0 node_modules/socket.io/node_modules/policyfile/examples/basic.fallback.js
  54. +5 −0 node_modules/socket.io/node_modules/policyfile/examples/basic.js
  55. +1 −0 node_modules/socket.io/node_modules/policyfile/index.js
  56. +289 −0 node_modules/socket.io/node_modules/policyfile/lib/server.js
  57. +32 −0 node_modules/socket.io/node_modules/policyfile/package.json
  58. +21 −0 node_modules/socket.io/node_modules/policyfile/tests/ssl/ssl.crt
  59. +27 −0 node_modules/socket.io/node_modules/policyfile/tests/ssl/ssl.private.key
  60. +231 −0 node_modules/socket.io/node_modules/policyfile/tests/unit.test.js
  61. +567 −0 node_modules/socket.io/node_modules/redis/README.md
  62. +184 −0 node_modules/socket.io/node_modules/redis/changelog.md
  63. +9 −0 node_modules/socket.io/node_modules/redis/eval_test.js
  64. +5 −0 node_modules/socket.io/node_modules/redis/examples/auth.js
  65. +33 −0 node_modules/socket.io/node_modules/redis/examples/backpressure_drain.js
  66. +24 −0 node_modules/socket.io/node_modules/redis/examples/extend.js
  67. +32 −0 node_modules/socket.io/node_modules/redis/examples/file.js
  68. +5 −0 node_modules/socket.io/node_modules/redis/examples/mget.js
  69. +10 −0 node_modules/socket.io/node_modules/redis/examples/monitor.js
  70. +46 −0 node_modules/socket.io/node_modules/redis/examples/multi.js
  71. +29 −0 node_modules/socket.io/node_modules/redis/examples/multi2.js
  72. +33 −0 node_modules/socket.io/node_modules/redis/examples/psubscribe.js
Sorry, we could not display the entire diff because too many files (461) changed.
View
25 index.js
@@ -27,8 +27,8 @@ module.exports = function (t, rewrites, options) {
return to
}
- function createProxy(req, resp, opts, stream) {
- var proxy = request(opts)
+ function createProxy(req, resp, proxyOpts, stream) {
+ var proxy = request(proxyOpts)
req.pipe(proxy)
if (stream) {
stream.pipe(proxy)
@@ -52,9 +52,18 @@ module.exports = function (t, rewrites, options) {
})
}
- function proxyFile(rewrite, req, resp) {
+ function proxyFile(rewrite) {
route(rewrite, function(req, resp) {
- filed(path.resolve(opts.attachments, rewrite.to)).pipe(resp)
+ var files = opts.attachments
+ if (!files) {
+ resp.statusCode = 404
+ return resp.end('not found')
+ }
+ if (_.isString(files) && files.match(/https?/i)) {
+ var to = opts.attachments + '/' + rewrite.to
+ return createProxy(req, resp, to)
+ }
+ filed(path.resolve(files, rewrite.to)).pipe(resp)
})
}
@@ -69,9 +78,9 @@ module.exports = function (t, rewrites, options) {
if (query.startkey) query.startkey = JSON.stringify(query.startkey)
if (query.endkey) query.endkey = JSON.stringify(query.endkey)
if (_.keys(query).length) to += "?" + qs.stringify(query)
- var opts = {url: to}
- if (rewrite.json) opts.json = rewrite.json
- createProxy(req, resp, opts, stream)
+ var proxyOpts = {url: to}
+ if (rewrite.json) proxyOpts.json = rewrite.json
+ createProxy(req, resp, proxyOpts, stream)
})
}
@@ -105,6 +114,6 @@ module.exports = function (t, rewrites, options) {
else return proxyFile(rewrite)
})
- t.route('/*').files(opts.attachments)
+ if (opts.attachments) t.route('/*').files(opts.attachments)
}
View
24 node_modules/filed/main.js
@@ -25,12 +25,12 @@ function File (options) {
self.index = options.index
self.on('pipe', function (src) {
- this.src = src;
+ this.src = src
})
this.buffering = true
- this.mimetype = mimetypes.lookup(this.path.slice(this.path.lastIndexOf('.')+1))
+ this.mimetype = options.mimetype || mimetypes.lookup(this.path.slice(this.path.lastIndexOf('.')+1))
var stopBuffering = function () {
self.buffering = false
@@ -82,13 +82,14 @@ function File (options) {
}
// Source is an HTTP Server Request
- if (self.src && (self.src.method === 'GET' || self.src.method === 'HEAD')) {
-
- self.dest.setHeader('content-type', self.mimetype)
- self.dest.setHeader('etag', self.etag)
- self.dest.setHeader('last-modified', self.lastmodified)
+ if (self.src && (self.src.method === 'GET' || self.src.method === 'HEAD') && self.dest) {
+ if (self.dest.setHeader) {
+ self.dest.setHeader('content-type', self.mimetype)
+ self.dest.setHeader('etag', self.etag)
+ self.dest.setHeader('last-modified', self.lastmodified)
+ }
- if (self.dest && self.dest.writeHead) {
+ if (self.dest.writeHead) {
if (self.src && self.src.headers) {
if (self.src.headers['if-none-match'] === self.etag ||
// Lazy last-modifed matching but it's faster than parsing Datetime
@@ -101,15 +102,17 @@ function File (options) {
// We're going to return the whole file
self.dest.statusCode = 200
self.dest.setHeader('content-length', stats.size)
- } else if (self.dest && !self.dest.writeHead) {
+ } else {
// Destination is not an HTTP response, GET and HEAD method are not allowed
return
}
- if (self.dest || self.src.method !== 'HEAD') {
+
+ if (self.src.method !== 'HEAD') {
fs.createReadStream(self.path).pipe(self.dest)
}
return
}
+
if (self.src && (self.src.method === 'PUT' || self.src.method === 'POST')) {
if (!err) {
// TODO handle overwrite case
@@ -125,6 +128,7 @@ function File (options) {
}
return
}
+
// Desination is an HTTP response, we already handled 404 and 500
if (self.dest && self.dest.writeHead) {
self.dest.statusCode = 200
View
2 node_modules/filed/package.json
@@ -1,7 +1,7 @@
{
"name": "filed",
"description": "Simplified file library.",
- "version": "0.0.4",
+ "version": "0.0.6",
"repository": {
"type": "git",
"url": "git://github.com/mikeal/filed.git"
View
3 node_modules/socket.io/.npmignore
@@ -0,0 +1,3 @@
+support
+test
+examples
View
7 node_modules/socket.io/.travis.yml
@@ -0,0 +1,7 @@
+language: node_js
+node_js:
+ - 0.4
+ - 0.6
+
+notifications:
+ irc: "irc.freenode.org#socket.io"
View
218 node_modules/socket.io/History.md
@@ -0,0 +1,218 @@
+
+0.9.0 / 2012-02-26
+==================
+
+ * Make it possible to use a regexp to match the socket.io resource URL.
+ We need this because we have to prefix the socket.io URL with a variable ID.
+ * Supplemental fix to gavinuhma/authfix, it looks like the same Access-Control-Origin logic is needed in the http and xhr-polling transports
+ * Updated express dep for windows compatibility.
+ * Combine two substr calls into one in decodePayload to improve performance
+ * Minor documentation fix
+ * Minor. Conform to style of other files.
+ * Switching setting to 'match origin protocol'
+ * Revert "Fixes leaking Redis subscriptions for #663. The local flag was not getting passed through onClientDisconnect()."
+ * Revert "Handle leaked dispatch:[id] subscription."
+ * Merge pull request #667 from dshaw/patch/redis-disconnect
+ * Handle leaked dispatch:[id] subscription.
+ * Fixes leaking Redis subscriptions for #663. The local flag was not getting passed through onClientDisconnect().
+ * Prevent memory leaking on uncompleted requests & add max post size limitation
+ * Fix for testcase
+ * Set Access-Control-Allow-Credentials true, regardless of cookie
+ * Remove assertvarnish from package as it breaks on 0.6
+ * Correct irc channel
+ * Added proper return after reserved field error
+ * Fixes manager.js failure to close connection after transport error has happened
+ * Added implicit port 80 for origin checks. fixes #638
+ * Fixed bug #432 in 0.8.7
+ * Set Access-Control-Allow-Origin header to origin to enable withCredentials
+ * Adding configuration variable matchOriginProtocol
+ * Fixes location mismatch error in Safari.
+ * Use tty to detect if we should add colors or not by default.
+ * Updated the package location.
+
+0.8.7 / 2011-11-05
+==================
+
+ * Fixed memory leaks in closed clients.
+ * Fixed memory leaks in namespaces.
+ * Fixed websocket handling for malformed requests from proxies. [einaros]
+ * Node 0.6 compatibility. [einaros] [3rd-Eden]
+ * Adapted tests and examples.
+
+0.8.6 / 2011-10-27
+==================
+
+ * Added JSON decoding on jsonp-polling transport.
+ * Fixed README example.
+ * Major speed optimizations [3rd-Eden] [einaros] [visionmedia]
+ * Added decode/encode benchmarks [visionmedia]
+ * Added support for black-listing client sent events.
+ * Fixed logging options, closes #540 [3rd-Eden]
+ * Added vary header for gzip [3rd-Eden]
+ * Properly cleaned up async websocket / flashsocket tests, after patching node-websocket-client
+ * Patched to properly shut down when a finishClose call is made during connection establishment
+ * Added support for socket.io version on url and far-future Expires [3rd-Eden] [getify]
+ * Began IE10 compatibility [einaros] [tbranyen]
+ * Misc WebSocket fixes [einaros]
+ * Added UTF8 to respone headers for htmlfile [3rd-Eden]
+
+0.8.5 / 2011-10-07
+==================
+
+ * Added websocket draft HyBi-16 support. [einaros]
+ * Fixed websocket continuation bugs. [einaros]
+ * Fixed flashsocket transport name.
+ * Fixed websocket tests.
+ * Ensured `parser#decodePayload` doesn't choke.
+ * Added http referrer verification to manager verifyOrigin.
+ * Added access control for cross domain xhr handshakes [3rd-Eden]
+ * Added support for automatic generation of socket.io files [3rd-Eden]
+ * Added websocket binary support [einaros]
+ * Added gzip support for socket.io.js [3rd-Eden]
+ * Expose socket.transport [3rd-Eden]
+ * Updated client.
+
+0.8.4 / 2011-09-06
+==================
+
+ * Client build
+
+0.8.3 / 2011-09-03
+==================
+
+ * Fixed `\n` parsing for non-JSON packets (fixes #479).
+ * Fixed parsing of certain unicode characters (fixes #451).
+ * Fixed transport message packet logging.
+ * Fixed emission of `error` event resulting in an uncaught exception if unhandled (fixes #476).
+ * Fixed; allow for falsy values as the configuration value of `log level` (fixes #491).
+ * Fixed repository URI in `package.json`. Fixes #504.
+ * Added text/plain content-type to handshake responses [einaros]
+ * Improved single byte writes [einaros]
+ * Updated socket.io-flashsocket default port from 843 to 10843 [3rd-Eden]
+ * Updated client.
+
+0.8.2 / 2011-08-29
+==================
+
+ * Updated client.
+
+0.8.1 / 2011-08-29
+==================
+
+ * Fixed utf8 bug in send framing in websocket [einaros]
+ * Fixed typo in docs [Znarkus]
+ * Fixed bug in send framing for over 64kB of data in websocket [einaros]
+ * Corrected ping handling in websocket transport [einaros]
+
+0.8.0 / 2011-08-28
+==================
+
+ * Updated to work with two-level websocket versioning. [einaros]
+ * Added hybi07 support. [einaros]
+ * Added hybi10 support. [einaros]
+ * Added http referrer verification to manager.js verifyOrigin. [einaors]
+
+0.7.11 / 2011-08-27
+===================
+
+ * Updated socket.io-client.
+
+0.7.10 / 2011-08-27
+===================
+
+ * Updated socket.io-client.
+
+0.7.9 / 2011-08-12
+==================
+
+ * Updated socket.io-client.
+ * Make sure we only do garbage collection when the server we receive is actually run.
+
+0.7.8 / 2011-08-08
+==================
+
+ * Changed; make sure sio#listen passes options to both HTTP server and socket.io manager.
+ * Added docs for sio#listen.
+ * Added options parameter support for Manager constructor.
+ * Added memory leaks tests and test-leaks Makefile task.
+ * Removed auto npm-linking from make test.
+ * Make sure that you can disable heartbeats. [3rd-Eden]
+ * Fixed rooms memory leak [3rd-Eden]
+ * Send response once we got all POST data, not immediately [Pita]
+ * Fixed onLeave behavior with missing clientsk [3rd-Eden]
+ * Prevent duplicate references in rooms.
+ * Added alias for `to` to `in` and `in` to `to`.
+ * Fixed roomClients definition.
+ * Removed dependency on redis for installation without npm [3rd-Eden]
+ * Expose path and querystring in handshakeData [3rd-Eden]
+
+0.7.7 / 2011-07-12
+==================
+
+ * Fixed double dispatch handling with emit to closed clients.
+ * Added test for emitting to closed clients to prevent regression.
+ * Fixed race condition in redis test.
+ * Changed Transport#end instrumentation.
+ * Leveraged $emit instead of emit internally.
+ * Made tests faster.
+ * Fixed double disconnect events.
+ * Fixed disconnect logic
+ * Simplified remote events handling in Socket.
+ * Increased testcase timeout.
+ * Fixed unknown room emitting (GH-291). [3rd-Eden]
+ * Fixed `address` in handshakeData. [3rd-Eden]
+ * Removed transports definition in chat example.
+ * Fixed room cleanup
+ * Fixed; make sure the client is cleaned up after booting.
+ * Make sure to mark the client as non-open if the connection is closed.
+ * Removed unneeded `buffer` declarations.
+ * Fixed; make sure to clear socket handlers and subscriptions upon transport close.
+
+0.7.6 / 2011-06-30
+==================
+
+ * Fixed general dispatching when a client has closed.
+
+0.7.5 / 2011-06-30
+==================
+
+ * Fixed dispatching to clients that are disconnected.
+
+0.7.4 / 2011-06-30
+==================
+
+ * Fixed; only clear handlers if they were set. [level09]
+
+0.7.3 / 2011-06-30
+==================
+
+ * Exposed handshake data to clients.
+ * Refactored dispatcher interface.
+ * Changed; Moved id generation method into the manager.
+ * Added sub-namespace authorization. [3rd-Eden]
+ * Changed; normalized SocketNamespace local eventing [dvv]
+ * Changed; Use packet.reason or default to 'packet' [3rd-Eden]
+ * Changed console.error to console.log.
+ * Fixed; bind both servers at the same time do that the test never times out.
+ * Added 304 support.
+ * Removed `Transport#name` for abstract interface.
+ * Changed; lazily require http and https module only when needed. [3rd-Eden]
+
+0.7.2 / 2011-06-22
+==================
+
+ * Make sure to write a packet (of type `noop`) when closing a poll.
+ This solves a problem with cross-domain requests being flagged as aborted and
+ reconnection being triggered.
+ * Added `noop` message type.
+
+0.7.1 / 2011-06-21
+==================
+
+ * Fixed cross-domain XHR.
+ * Added CORS test to xhr-polling suite.
+
+0.7.0 / 2010-06-21
+==================
+
+ * http://socket.io/announcement.html
View
31 node_modules/socket.io/Makefile
@@ -0,0 +1,31 @@
+
+ALL_TESTS = $(shell find test/ -name '*.test.js')
+ALL_BENCH = $(shell find benchmarks -name '*.bench.js')
+
+run-tests:
+ @./node_modules/.bin/expresso \
+ -t 3000 \
+ -I support \
+ --serial \
+ $(TESTFLAGS) \
+ $(TESTS)
+
+test:
+ @$(MAKE) NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests
+
+test-cov:
+ @TESTFLAGS=--cov $(MAKE) test
+
+test-leaks:
+ @ls test/leaks/* | xargs node --expose_debug_as=debug --expose_gc
+
+run-bench:
+ @node $(PROFILEFLAGS) benchmarks/runner.js
+
+bench:
+ @$(MAKE) BENCHMARKS="$(ALL_BENCH)" run-bench
+
+profile:
+ @PROFILEFLAGS='--prof --trace-opt --trace-bailout --trace-deopt' $(MAKE) bench
+
+.PHONY: test bench profile
View
343 node_modules/socket.io/Readme.md
@@ -0,0 +1,343 @@
+# Socket.IO
+
+Socket.IO is a Node.JS project that makes WebSockets and realtime possible in
+all browsers. It also enhances WebSockets by providing built-in multiplexing,
+horizontal scalability, automatic JSON encoding/decoding, and more.
+
+## How to Install
+
+ npm install socket.io
+
+## How to use
+
+First, require `socket.io`:
+
+```js
+var io = require('socket.io');
+```
+
+Next, attach it to a HTTP/HTTPS server. If you're using the fantastic `express`
+web framework:
+
+```js
+var app = express.createServer()
+ , io = io.listen(app);
+
+app.listen(80);
+
+io.sockets.on('connection', function (socket) {
+ socket.emit('news', { hello: 'world' });
+ socket.on('my other event', function (data) {
+ console.log(data);
+ });
+});
+```
+
+Finally, load it from the client side code:
+
+```html
+<script src="/socket.io/socket.io.js"></script>
+<script>
+ var socket = io.connect('http://localhost');
+ socket.on('news', function (data) {
+ console.log(data);
+ socket.emit('my other event', { my: 'data' });
+ });
+</script>
+```
+
+For more thorough examples, look at the `examples/` directory.
+
+## Short recipes
+
+### Sending and receiving events.
+
+Socket.IO allows you to emit and receive custom events.
+Besides `connect`, `message` and `disconnect`, you can emit custom events:
+
+```js
+// note, io.listen(<port>) will create a http server for you
+var io = require('socket.io').listen(80);
+
+io.sockets.on('connection', function (socket) {
+ io.sockets.emit('this', { will: 'be received by everyone' });
+
+ socket.on('private message', function (from, msg) {
+ console.log('I received a private message by ', from, ' saying ', msg);
+ });
+
+ socket.on('disconnect', function () {
+ io.sockets.emit('user disconnected');
+ });
+});
+```
+
+### Storing data associated to a client
+
+Sometimes it's necessary to store data associated with a client that's
+necessary for the duration of the session.
+
+#### Server side
+
+```js
+var io = require('socket.io').listen(80);
+
+io.sockets.on('connection', function (socket) {
+ socket.on('set nickname', function (name) {
+ socket.set('nickname', name, function () { socket.emit('ready'); });
+ });
+
+ socket.on('msg', function () {
+ socket.get('nickname', function (err, name) {
+ console.log('Chat message by ', name);
+ });
+ });
+});
+```
+
+#### Client side
+
+```html
+<script>
+ var socket = io.connect('http://localhost');
+
+ socket.on('connect', function () {
+ socket.emit('set nickname', confirm('What is your nickname?'));
+ socket.on('ready', function () {
+ console.log('Connected !');
+ socket.emit('msg', confirm('What is your message?'));
+ });
+ });
+</script>
+```
+
+### Restricting yourself to a namespace
+
+If you have control over all the messages and events emitted for a particular
+application, using the default `/` namespace works.
+
+If you want to leverage 3rd-party code, or produce code to share with others,
+socket.io provides a way of namespacing a `socket`.
+
+This has the benefit of `multiplexing` a single connection. Instead of
+socket.io using two `WebSocket` connections, it'll use one.
+
+The following example defines a socket that listens on '/chat' and one for
+'/news':
+
+#### Server side
+
+```js
+var io = require('socket.io').listen(80);
+
+var chat = io
+ .of('/chat')
+ .on('connection', function (socket) {
+ socket.emit('a message', { that: 'only', '/chat': 'will get' });
+ chat.emit('a message', { everyone: 'in', '/chat': 'will get' });
+ });
+
+var news = io
+ .of('/news');
+ .on('connection', function (socket) {
+ socket.emit('item', { news: 'item' });
+ });
+```
+
+#### Client side:
+
+```html
+<script>
+ var chat = io.connect('http://localhost/chat')
+ , news = io.connect('http://localhost/news');
+
+ chat.on('connect', function () {
+ chat.emit('hi!');
+ });
+
+ news.on('news', function () {
+ news.emit('woot');
+ });
+</script>
+```
+
+### Sending volatile messages.
+
+Sometimes certain messages can be dropped. Let's say you have an app that
+shows realtime tweets for the keyword `bieber`.
+
+If a certain client is not ready to receive messages (because of network slowness
+or other issues, or because he's connected through long polling and is in the
+middle of a request-response cycle), if he doesn't receive ALL the tweets related
+to bieber your application won't suffer.
+
+In that case, you might want to send those messages as volatile messages.
+
+#### Server side
+
+```js
+var io = require('socket.io').listen(80);
+
+io.sockets.on('connection', function (socket) {
+ var tweets = setInterval(function () {
+ getBieberTweet(function (tweet) {
+ socket.volatile.emit('bieber tweet', tweet);
+ });
+ }, 100);
+
+ socket.on('disconnect', function () {
+ clearInterval(tweets);
+ });
+});
+```
+
+#### Client side
+
+In the client side, messages are received the same way whether they're volatile
+or not.
+
+### Getting acknowledgements
+
+Sometimes, you might want to get a callback when the client confirmed the message
+reception.
+
+To do this, simply pass a function as the last parameter of `.send` or `.emit`.
+What's more, when you use `.emit`, the acknowledgement is done by you, which
+means you can also pass data along:
+
+#### Server side
+
+```js
+var io = require('socket.io').listen(80);
+
+io.sockets.on('connection', function (socket) {
+ socket.on('ferret', function (name, fn) {
+ fn('woot');
+ });
+});
+```
+
+#### Client side
+
+```html
+<script>
+ var socket = io.connect(); // TIP: .connect with no args does auto-discovery
+ socket.on('connect', function () { // TIP: you can avoid listening on `connect` and listen on events directly too!
+ socket.emit('ferret', 'tobi', function (data) {
+ console.log(data); // data will be 'woot'
+ });
+ });
+</script>
+```
+
+### Broadcasting messages
+
+To broadcast, simply add a `broadcast` flag to `emit` and `send` method calls.
+Broadcasting means sending a message to everyone else except for the socket
+that starts it.
+
+#### Server side
+
+```js
+var io = require('socket.io').listen(80);
+
+io.sockets.on('connection', function (socket) {
+ socket.broadcast.emit('user connected');
+ socket.broadcast.json.send({ a: 'message' });
+});
+```
+
+### Rooms
+
+Sometimes you want to put certain sockets in the same room, so that it's easy
+to broadcast to all of them together.
+
+Think of this as built-in channels for sockets. Sockets `join` and `leave`
+rooms in each socket.
+
+#### Server side
+
+```js
+var io = require('socket.io').listen(80);
+
+io.sockets.on('connection', function (socket) {
+ socket.join('justin bieber fans');
+ socket.broadcast.to('justin bieber fans').emit('new fan');
+ io.sockets.in('rammstein fans').emit('new non-fan');
+});
+```
+
+### Using it just as a cross-browser WebSocket
+
+If you just want the WebSocket semantics, you can do that too.
+Simply leverage `send` and listen on the `message` event:
+
+#### Server side
+
+```js
+var io = require('socket.io').listen(80);
+
+io.sockets.on('connection', function (socket) {
+ socket.on('message', function () { });
+ socket.on('disconnect', function () { });
+});
+```
+
+#### Client side
+
+```html
+<script>
+ var socket = io.connect('http://localhost/');
+ socket.on('connect', function () {
+ socket.send('hi');
+
+ socket.on('message', function (msg) {
+ // my msg
+ });
+ });
+</script>
+```
+
+### Changing configuration
+
+Configuration in socket.io is TJ-style:
+
+#### Server side
+
+```js
+var io = require('socket.io').listen(80);
+
+io.configure(function () {
+ io.set('transports', ['websocket', 'flashsocket', 'xhr-polling']);
+});
+
+io.configure('development', function () {
+ io.set('transports', ['websocket', 'xhr-polling']);
+ io.enable('log');
+});
+```
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2011 Guillermo Rauch &lt;guillermo@learnboost.com&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
64 node_modules/socket.io/benchmarks/decode.bench.js
@@ -0,0 +1,64 @@
+
+/**
+ * Module dependencies.
+ */
+
+var benchmark = require('benchmark')
+ , colors = require('colors')
+ , io = require('../')
+ , parser = io.parser
+ , suite = new benchmark.Suite('Decode packet');
+
+suite.add('string', function () {
+ parser.decodePacket('4:::"2"');
+});
+
+suite.add('event', function () {
+ parser.decodePacket('5:::{"name":"woot"}');
+});
+
+suite.add('event+ack', function () {
+ parser.decodePacket('5:1+::{"name":"tobi"}');
+});
+
+suite.add('event+data', function () {
+ parser.decodePacket('5:::{"name":"edwald","args":[{"a": "b"},2,"3"]}');
+});
+
+suite.add('heartbeat', function () {
+ parser.decodePacket('2:::');
+});
+
+suite.add('error', function () {
+ parser.decodePacket('7:::2+0');
+});
+
+var payload = parser.encodePayload([
+ parser.encodePacket({ type: 'message', data: '5', endpoint: '' })
+ , parser.encodePacket({ type: 'message', data: '53d', endpoint: '' })
+ , parser.encodePacket({ type: 'message', data: 'foobar', endpoint: '' })
+ , parser.encodePacket({ type: 'message', data: 'foobarbaz', endpoint: '' })
+ , parser.encodePacket({ type: 'message', data: 'foobarbazfoobarbaz', endpoint: '' })
+ , parser.encodePacket({ type: 'message', data: 'foobarbaz', endpoint: '' })
+ , parser.encodePacket({ type: 'message', data: 'foobar', endpoint: '' })
+]);
+
+suite.add('payload', function () {
+ parser.decodePayload(payload);
+});
+
+suite.on('cycle', function (bench, details) {
+ console.log('\n' + suite.name.grey, details.name.white.bold);
+ console.log([
+ details.hz.toFixed(2).cyan + ' ops/sec'.grey
+ , details.count.toString().white + ' times executed'.grey
+ , 'benchmark took '.grey + details.times.elapsed.toString().white + ' sec.'.grey
+ ,
+ ].join(', '.grey));
+});
+
+if (!module.parent) {
+ suite.run();
+} else {
+ module.exports = suite;
+}
View
90 node_modules/socket.io/benchmarks/encode.bench.js
@@ -0,0 +1,90 @@
+
+/**
+ * Module dependencies.
+ */
+
+var benchmark = require('benchmark')
+ , colors = require('colors')
+ , io = require('../')
+ , parser = io.parser
+ , suite = new benchmark.Suite('Encode packet');
+
+suite.add('string', function () {
+ parser.encodePacket({
+ type: 'json'
+ , endpoint: ''
+ , data: '2'
+ });
+});
+
+suite.add('event', function () {
+ parser.encodePacket({
+ type: 'event'
+ , name: 'woot'
+ , endpoint: ''
+ , args: []
+ });
+});
+
+suite.add('event+ack', function () {
+ parser.encodePacket({
+ type: 'json'
+ , id: 1
+ , ack: 'data'
+ , endpoint: ''
+ , data: { a: 'b' }
+ });
+});
+
+suite.add('event+data', function () {
+ parser.encodePacket({
+ type: 'event'
+ , name: 'edwald'
+ , endpoint: ''
+ , args: [{a: 'b'}, 2, '3']
+ });
+});
+
+suite.add('heartbeat', function () {
+ parser.encodePacket({
+ type: 'heartbeat'
+ , endpoint: ''
+ })
+});
+
+suite.add('error', function () {
+ parser.encodePacket({
+ type: 'error'
+ , reason: 'unauthorized'
+ , advice: 'reconnect'
+ , endpoint: ''
+ })
+})
+
+suite.add('payload', function () {
+ parser.encodePayload([
+ parser.encodePacket({ type: 'message', data: '5', endpoint: '' })
+ , parser.encodePacket({ type: 'message', data: '53d', endpoint: '' })
+ , parser.encodePacket({ type: 'message', data: 'foobar', endpoint: '' })
+ , parser.encodePacket({ type: 'message', data: 'foobarbaz', endpoint: '' })
+ , parser.encodePacket({ type: 'message', data: 'foobarbazfoobarbaz', endpoint: '' })
+ , parser.encodePacket({ type: 'message', data: 'foobarbaz', endpoint: '' })
+ , parser.encodePacket({ type: 'message', data: 'foobar', endpoint: '' })
+ ]);
+});
+
+suite.on('cycle', function (bench, details) {
+ console.log('\n' + suite.name.grey, details.name.white.bold);
+ console.log([
+ details.hz.toFixed(2).cyan + ' ops/sec'.grey
+ , details.count.toString().white + ' times executed'.grey
+ , 'benchmark took '.grey + details.times.elapsed.toString().white + ' sec.'.grey
+ ,
+ ].join(', '.grey));
+});
+
+if (!module.parent) {
+ suite.run();
+} else {
+ module.exports = suite;
+}
View
55 node_modules/socket.io/benchmarks/runner.js
@@ -0,0 +1,55 @@
+/**
+ * Benchmark runner dependencies
+ */
+
+var colors = require('colors')
+ , path = require('path');
+
+/**
+ * Find all the benchmarks
+ */
+
+var benchmarks_files = process.env.BENCHMARKS.split(' ')
+ , all = [].concat(benchmarks_files)
+ , first = all.shift()
+ , benchmarks = {};
+
+// find the benchmarks and load them all in our obj
+benchmarks_files.forEach(function (file) {
+ benchmarks[file] = require(path.join(__dirname, '..', file));
+});
+
+// setup the complete listeners
+benchmarks_files.forEach(function (file) {
+ var benchmark = benchmarks[file]
+ , next_file = all.shift()
+ , next = benchmarks[next_file];
+
+ /**
+ * Generate a oncomplete function for the tests, either we are done or we
+ * have more benchmarks to process.
+ */
+
+ function complete () {
+ if (!next) {
+ console.log(
+ '\n\nBenchmark completed in'.grey
+ , (Date.now() - start).toString().green + ' ms'.grey
+ );
+ } else {
+ console.log('\nStarting benchmark '.grey + next_file.yellow);
+ next.run();
+ }
+ }
+
+ // attach the listener
+ benchmark.on('complete', complete);
+});
+
+/**
+ * Start the benchmark
+ */
+
+var start = Date.now();
+console.log('Starting benchmark '.grey + first.yellow);
+benchmarks[first].run();
View
80 node_modules/socket.io/examples/chat/app.js
@@ -0,0 +1,80 @@
+/**
+ * Module dependencies.
+ */
+
+var express = require('express')
+ , stylus = require('stylus')
+ , nib = require('nib')
+ , sio = require('../../lib/socket.io');
+
+/**
+ * App.
+ */
+
+var app = express.createServer();
+
+/**
+ * App configuration.
+ */
+
+app.configure(function () {
+ app.use(stylus.middleware({ src: __dirname + '/public', compile: compile }));
+ app.use(express.static(__dirname + '/public'));
+ app.set('views', __dirname);
+ app.set('view engine', 'jade');
+
+ function compile (str, path) {
+ return stylus(str)
+ .set('filename', path)
+ .use(nib());
+ };
+});
+
+/**
+ * App routes.
+ */
+
+app.get('/', function (req, res) {
+ res.render('index', { layout: false });
+});
+
+/**
+ * App listen.
+ */
+
+app.listen(3000, function () {
+ var addr = app.address();
+ console.log(' app listening on http://' + addr.address + ':' + addr.port);
+});
+
+/**
+ * Socket.IO server (single process only)
+ */
+
+var io = sio.listen(app)
+ , nicknames = {};
+
+io.sockets.on('connection', function (socket) {
+ socket.on('user message', function (msg) {
+ socket.broadcast.emit('user message', socket.nickname, msg);
+ });
+
+ socket.on('nickname', function (nick, fn) {
+ if (nicknames[nick]) {
+ fn(true);
+ } else {
+ fn(false);
+ nicknames[nick] = socket.nickname = nick;
+ socket.broadcast.emit('announcement', nick + ' connected');
+ io.sockets.emit('nicknames', nicknames);
+ }
+ });
+
+ socket.on('disconnect', function () {
+ if (!socket.nickname) return;
+
+ delete nicknames[socket.nickname];
+ socket.broadcast.emit('announcement', socket.nickname + ' disconnected');
+ socket.broadcast.emit('nicknames', nicknames);
+ });
+});
View
83 node_modules/socket.io/examples/chat/index.jade
@@ -0,0 +1,83 @@
+doctype 5
+html
+ head
+ link(href='/stylesheets/style.css', rel='stylesheet')
+ script(src='http://code.jquery.com/jquery-1.6.1.min.js')
+ script(src='/socket.io/socket.io.js')
+ script
+ // socket.io specific code
+ var socket = io.connect();
+
+ socket.on('connect', function () {
+ $('#chat').addClass('connected');
+ });
+
+ socket.on('announcement', function (msg) {
+ $('#lines').append($('<p>').append($('<em>').text(msg)));
+ });
+
+ socket.on('nicknames', function (nicknames) {
+ $('#nicknames').empty().append($('<span>Online: </span>'));
+ for (var i in nicknames) {
+ $('#nicknames').append($('<b>').text(nicknames[i]));
+ }
+ });
+
+ socket.on('user message', message);
+ socket.on('reconnect', function () {
+ $('#lines').remove();
+ message('System', 'Reconnected to the server');
+ });
+
+ socket.on('reconnecting', function () {
+ message('System', 'Attempting to re-connect to the server');
+ });
+
+ socket.on('error', function (e) {
+ message('System', e ? e : 'A unknown error occurred');
+ });
+
+ function message (from, msg) {
+ $('#lines').append($('<p>').append($('<b>').text(from), msg));
+ }
+
+ // dom manipulation
+ $(function () {
+ $('#set-nickname').submit(function (ev) {
+ socket.emit('nickname', $('#nick').val(), function (set) {
+ if (!set) {
+ clear();
+ return $('#chat').addClass('nickname-set');
+ }
+ $('#nickname-err').css('visibility', 'visible');
+ });
+ return false;
+ });
+
+ $('#send-message').submit(function () {
+ message('me', $('#message').val());
+ socket.emit('user message', $('#message').val());
+ clear();
+ $('#lines').get(0).scrollTop = 10000000;
+ return false;
+ });
+
+ function clear () {
+ $('#message').val('').focus();
+ };
+ });
+ body
+ #chat
+ #nickname
+ form.wrap#set-nickname
+ p Please type in your nickname and press enter.
+ input#nick
+ p#nickname-err Nickname already in use
+ #connecting
+ .wrap Connecting to socket.io server
+ #messages
+ #nicknames
+ #lines
+ form#send-message
+ input#message
+ button Send
View
11 node_modules/socket.io/examples/chat/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "chat.io"
+ , "description": "example chat application with socket.io"
+ , "version": "0.0.1"
+ , "dependencies": {
+ "express": "2.5.5"
+ , "jade": "0.16.4"
+ , "stylus": "0.19.0"
+ , "nib": "0.2.0"
+ }
+}
View
96 node_modules/socket.io/examples/chat/public/stylesheets/mixins.styl
@@ -0,0 +1,96 @@
+border-radius(n)
+ -webkit-border-radius n
+ -moz-border-radius n
+ border-radius n
+
+// replace str with val
+
+replace(expr, str, val)
+ expr = clone(expr)
+ for e, i in expr
+ if str == e
+ expr[i] = val
+ expr
+
+// normalize gradient point (webkit)
+
+grad-point(pos)
+ if length(pos) == 1
+ return left pos if pos in (top bottom)
+ return pos top if pos in (left right)
+ else if pos[0] in (top bottom)
+ pos[1] pos[0]
+ else
+ pos
+
+// implicit color stop position
+
+pos-in-stops(i, stops)
+ len = length(stops)
+ if len - 1 == i
+ 100%
+ else if i
+ unit(i / len * 100, '%')
+ else
+ 0%
+
+// normalize color stops
+// - (color pos) -> (pos color)
+// - (color) -> (implied-pos color)
+
+normalize-stops(stops)
+ stops = clone(stops)
+ for stop, i in stops
+ if length(stop) == 1
+ color = stop[0]
+ stop[0] = pos-in-stops(i, stops)
+ stop[1] = color
+ else if typeof(stop[1]) == 'unit'
+ pos = stop[1]
+ stop[1] = stop[0]
+ stop[0] = pos
+ stops
+
+// join color stops with the given translation function
+
+join-stops(stops, translate)
+ str = ''
+ len = length(stops)
+ for stop, i in stops
+ str += ', ' if i
+ pos = stop[0]
+ color = stop[1]
+ str += translate(color, pos)
+ unquote(str)
+
+// webkit translation function
+
+webkit-stop(color, pos)
+ s('color-stop(%d, %s)', pos / 100, color)
+
+// mozilla translation function
+
+moz-stop(color, pos)
+ s('%s %s', color, pos)
+
+// create a linear gradient with the given start
+// position, followed by color stops
+
+linear-gradient(start, stops...)
+ error('color stops required') unless length(stops)
+ prop = current-property[0]
+ val = current-property[1]
+ stops = normalize-stops(stops)
+
+ // webkit
+ end = grad-point(opposite-position(start))
+ webkit = s('-webkit-gradient(linear, %s, %s, %s)', grad-point(start), end, join-stops(stops, webkit-stop))
+ add-property(prop, replace(val, '__CALL__', webkit))
+
+ // moz
+ stops = join-stops(stops, moz-stop)
+ moz = s('-moz-linear-gradient(%s, %s)', start, stops)
+ add-property(prop, replace(val, '__CALL__', moz))
+
+ // literal
+ s('linear-gradient(%s, %s)', start, stops)
View
188 node_modules/socket.io/examples/chat/public/stylesheets/style.css
@@ -0,0 +1,188 @@
+#chat,
+#nickname,
+#messages {
+ width: 600px;
+}
+#chat {
+ position: relative;
+ border: 1px solid #ccc;
+}
+#nickname,
+#connecting {
+ position: absolute;
+ height: 410px;
+ z-index: 100;
+ left: 0;
+ top: 0;
+ background: #fff;
+ text-align: center;
+ width: 600px;
+ font: 15px Georgia;
+ color: #666;
+ display: block;
+}
+#nickname .wrap,
+#connecting .wrap {
+ padding-top: 150px;
+}
+#nickname input {
+ border: 1px solid #ccc;
+ padding: 10px;
+}
+#nickname input:focus {
+ border-color: #999;
+ outline: 0;
+}
+#nickname #nickname-err {
+ color: #8b0000;
+ font-size: 12px;
+ visibility: hidden;
+}
+.connected #connecting {
+ display: none;
+}
+.nickname-set #nickname {
+ display: none;
+}
+#messages {
+ height: 380px;
+ background: #eee;
+}
+#messages em {
+ text-shadow: 0 1px 0 #fff;
+ color: #999;
+}
+#messages p {
+ padding: 0;
+ margin: 0;
+ font: 12px Helvetica, Arial;
+ padding: 5px 10px;
+}
+#messages p b {
+ display: inline-block;
+ padding-right: 10px;
+}
+#messages p:nth-child(even) {
+ background: #fafafa;
+}
+#messages #nicknames {
+ background: #ccc;
+ padding: 2px 4px 4px;
+ font: 11px Helvetica;
+}
+#messages #nicknames span {
+ color: #000;
+}
+#messages #nicknames b {
+ display: inline-block;
+ color: #fff;
+ background: #999;
+ padding: 3px 6px;
+ margin-right: 5px;
+ -webkit-border-radius: 10px;
+ -moz-border-radius: 10px;
+ border-radius: 10px;
+ text-shadow: 0 1px 0 #666;
+}
+#messages #lines {
+ height: 355px;
+ overflow: auto;
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+#messages #lines::-webkit-scrollbar {
+ width: 6px;
+ height: 6px;
+}
+#messages #lines::-webkit-scrollbar-button:start:decrement,
+#messages #lines ::-webkit-scrollbar-button:end:increment {
+ display: block;
+ height: 10px;
+}
+#messages #lines::-webkit-scrollbar-button:vertical:increment {
+ background-color: #fff;
+}
+#messages #lines::-webkit-scrollbar-track-piece {
+ background-color: #fff;
+ -webkit-border-radius: 3px;
+}
+#messages #lines::-webkit-scrollbar-thumb:vertical {
+ height: 50px;
+ background-color: #ccc;
+ -webkit-border-radius: 3px;
+}
+#messages #lines::-webkit-scrollbar-thumb:horizontal {
+ width: 50px;
+ background-color: #fff;
+ -webkit-border-radius: 3px;
+}
+#send-message {
+ background: #fff;
+ position: relative;
+}
+#send-message input {
+ border: none;
+ height: 30px;
+ padding: 0 10px;
+ line-height: 30px;
+ vertical-align: middle;
+ width: 580px;
+}
+#send-message input:focus {
+ outline: 0;
+}
+#send-message button {
+ position: absolute;
+ top: 5px;
+ right: 5px;
+}
+button {
+ margin: 0;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ display: inline-block;
+ text-decoration: none;
+ background: #43a1f7;
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #43a1f7), color-stop(1, #377ad0));
+ background: -webkit-linear-gradient(top, #43a1f7 0%, #377ad0 100%);
+ background: -moz-linear-gradient(top, #43a1f7 0%, #377ad0 100%);
+ background: linear-gradient(top, #43a1f7 0%, #377ad0 100%);
+ border: 1px solid #2e70c4;
+ -webkit-border-radius: 16px;
+ -moz-border-radius: 16px;
+ border-radius: 16px;
+ color: #fff;
+ font-family: "lucida grande", sans-serif;
+ font-size: 11px;
+ font-weight: normal;
+ line-height: 1;
+ padding: 3px 10px 5px 10px;
+ text-align: center;
+ text-shadow: 0 -1px 1px #2d6dc0;
+}
+button:hover,
+button.hover {
+ background: darker;
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #43a1f7), color-stop(1, #2e70c4));
+ background: -webkit-linear-gradient(top, #43a1f7 0%, #2e70c4 100%);
+ background: -moz-linear-gradient(top, #43a1f7 0%, #2e70c4 100%);
+ background: linear-gradient(top, #43a1f7 0%, #2e70c4 100%);
+ border: 1px solid #2e70c4;
+ cursor: pointer;
+ text-shadow: 0 -1px 1px #2c6bbb;
+}
+button:active,
+button.active {
+ background: #2e70c4;
+ border: 1px solid #2e70c4;
+ border-bottom: 1px solid #2861aa;
+ text-shadow: 0 -1px 1px #2b67b5;
+}
+button:focus,
+button.focus {
+ outline: none;
+ -webkit-box-shadow: 0 1px 0 0 rgba(255,255,255,0.4), 0 0 4px 0 #377ad0;
+ -moz-box-shadow: 0 1px 0 0 rgba(255,255,255,0.4), 0 0 4px 0 #377ad0;
+ box-shadow: 0 1px 0 0 rgba(255,255,255,0.4), 0 0 4px 0 #377ad0;
+}
View
118 node_modules/socket.io/examples/chat/public/stylesheets/style.styl
@@ -0,0 +1,118 @@
+@import 'nib'
+
+#chat, #nickname, #messages
+ width 600px
+
+#chat
+ position relative
+ border 1px solid #ccc
+
+#nickname, #connecting
+ position absolute
+ height 410px
+ z-index 100
+ left 0
+ top 0
+ background #fff
+ text-align center
+ width 600px
+ font 15px Georgia
+ color #666
+ display block
+ .wrap
+ padding-top 150px
+
+#nickname
+ input
+ border 1px solid #ccc
+ padding 10px
+ &:focus
+ border-color #999
+ outline 0
+ #nickname-err
+ color darkred
+ font-size 12px
+ visibility hidden
+
+.connected
+ #connecting
+ display none
+
+.nickname-set
+ #nickname
+ display none
+
+#messages
+ height 380px
+ background #eee
+ em
+ text-shadow 0 1px 0 #fff
+ color #999
+ p
+ padding 0
+ margin 0
+ font 12px Helvetica, Arial
+ padding 5px 10px
+ b
+ display inline-block
+ padding-right 10px
+ p:nth-child(even)
+ background #fafafa
+ #nicknames
+ background #ccc
+ padding 2px 4px 4px
+ font 11px Helvetica
+ span
+ color black
+ b
+ display inline-block
+ color #fff
+ background #999
+ padding 3px 6px
+ margin-right 5px
+ border-radius 10px
+ text-shadow 0 1px 0 #666
+ #lines
+ height 355px
+ overflow auto
+ overflow-x hidden
+ overflow-y auto
+ &::-webkit-scrollbar
+ width 6px
+ height 6px
+ &::-webkit-scrollbar-button:start:decrement, ::-webkit-scrollbar-button:end:increment
+ display block
+ height 10px
+ &::-webkit-scrollbar-button:vertical:increment
+ background-color #fff
+ &::-webkit-scrollbar-track-piece
+ background-color #fff
+ -webkit-border-radius 3px
+ &::-webkit-scrollbar-thumb:vertical
+ height 50px
+ background-color #ccc
+ -webkit-border-radius 3px
+ &::-webkit-scrollbar-thumb:horizontal
+ width 50px
+ background-color #fff
+ -webkit-border-radius 3px
+
+#send-message
+ background #fff
+ position relative
+ input
+ border none
+ height 30px
+ padding 0 10px
+ line-height 30px
+ vertical-align middle
+ width 580px
+ &:focus
+ outline 0
+ button
+ position absolute
+ top 5px
+ right 5px
+
+button
+ download-button()
View
74 node_modules/socket.io/examples/irc-output/app.js
@@ -0,0 +1,74 @@
+/**
+ * Module dependencies.
+ */
+
+var express = require('express')
+ , stylus = require('stylus')
+ , nib = require('nib')
+ , sio = require('../../lib/socket.io')
+ , irc = require('./irc');
+
+/**
+ * App.
+ */
+
+var app = express.createServer();
+
+/**
+ * App configuration.
+ */
+
+app.configure(function () {
+ app.use(stylus.middleware({ src: __dirname + '/public', compile: compile }))
+ app.use(express.static(__dirname + '/public'));
+ app.set('views', __dirname);
+ app.set('view engine', 'jade');
+
+ function compile (str, path) {
+ return stylus(str)
+ .set('filename', path)
+ .use(nib());
+ };
+});
+
+/**
+ * App routes.
+ */
+
+app.get('/', function (req, res) {
+ res.render('index', { layout: false });
+});
+
+/**
+ * App listen.
+ */
+
+app.listen(3000, function () {
+ var addr = app.address();
+ console.log(' app listening on http://' + addr.address + ':' + addr.port);
+});
+
+/**
+ * Socket.IO server
+ */
+
+var io = sio.listen(app)
+
+/**
+ * Connect to IRC.
+ */
+
+var client = new irc.Client('irc.freenode.net', 6667);
+client.connect('socketio\\test\\' + String(Math.random()).substr(-3));
+client.on('001', function () {
+ this.send('JOIN', '#node.js');
+});
+client.on('PART', function (prefix) {
+ io.sockets.emit('announcement', irc.user(prefix) + ' left the channel');
+});
+client.on('JOIN', function (prefix) {
+ io.sockets.emit('announcement', irc.user(prefix) + ' joined the channel');
+});
+client.on('PRIVMSG', function (prefix, channel, text) {
+ io.sockets.emit('irc message', irc.user(prefix), text);
+});
View
28 node_modules/socket.io/examples/irc-output/index.jade
@@ -0,0 +1,28 @@
+doctype 5
+html
+ head
+ link(href='/stylesheets/style.css', rel='stylesheet')
+ script(src='http://code.jquery.com/jquery-1.6.1.min.js')
+ script(src='/socket.io/socket.io.js')
+ script
+ var socket = io.connect();
+
+ socket.on('connect', function () {
+ $('#irc').addClass('connected');
+ });
+
+ socket.on('announcement', function (msg) {
+ $('#messages').append($('<p>').append($('<em>').text(msg)));
+ $('#messages').get(0).scrollTop = 10000000;
+ });
+
+ socket.on('irc message', function (user, msg) {
+ $('#messages').append($('<p>').append($('<b>').text(user), msg));
+ $('#messages').get(0).scrollTop = 10000000;
+ });
+ body
+ h2 Node.JS IRC
+ #irc
+ #connecting
+ .wrap Connecting to socket.io server
+ #messages
View
164 node_modules/socket.io/examples/irc-output/irc.js
@@ -0,0 +1,164 @@
+/**
+ * From https://github.com/felixge/nodelog/
+ */
+
+var sys = require('util');
+var tcp = require('net');
+var irc = exports;
+
+function bind(fn, scope) {
+ var bindArgs = Array.prototype.slice.call(arguments);
+ bindArgs.shift();
+ bindArgs.shift();
+
+ return function() {
+ var args = Array.prototype.slice.call(arguments);
+ fn.apply(scope, bindArgs.concat(args));
+ };
+}
+
+function each(set, iterator) {
+ for (var i = 0; i < set.length; i++) {
+ var r = iterator(set[i], i);
+ if (r === false) {
+ return;
+ }
+ }
+}
+
+var Client = irc.Client = function(host, port) {
+ this.host = host || 'localhost';
+ this.port = port || 6667;
+
+ this.connection = null;
+ this.buffer = '';
+ this.encoding = 'utf8';
+ this.timeout = 10 * 60 * 60 * 1000;
+
+ this.nick = null;
+ this.user = null;
+ this.real = null;
+}
+sys.inherits(Client, process.EventEmitter);
+
+Client.prototype.connect = function(nick, user, real) {
+ var connection = tcp.createConnection(this.port, this.host);
+ connection.setEncoding(this.encoding);
+ connection.setTimeout(this.timeout);
+ connection.addListener('connect', bind(this.onConnect, this));
+ connection.addListener('data', bind(this.onReceive, this));
+ connection.addListener('end', bind(this.onEof, this));
+ connection.addListener('timeout', bind(this.onTimeout, this));
+ connection.addListener('close', bind(this.onClose, this));
+
+ this.nick = nick;
+ this.user = user || 'guest';
+ this.real = real || 'Guest';
+
+ this.connection = connection;
+};
+
+Client.prototype.disconnect = function(why) {
+ if (this.connection.readyState !== 'closed') {
+ this.connection.close();
+ sys.puts('disconnected (reason: '+why+')');
+ this.emit('DISCONNECT', why);
+ }
+};
+
+Client.prototype.send = function(arg1) {
+ if (this.connection.readyState !== 'open') {
+ return this.disconnect('cannot send with readyState: '+this.connection.readyState);
+ }
+
+ var message = [];
+ for (var i = 0; i< arguments.length; i++) {
+ if (arguments[i]) {
+ message.push(arguments[i]);
+ }
+ }
+ message = message.join(' ');
+
+ sys.puts('> '+message);
+ message = message + "\r\n";
+ this.connection.write(message, this.encoding);
+};
+
+Client.prototype.parse = function(message) {
+ var match = message.match(/(?:(:[^\s]+) )?([^\s]+) (.+)/);
+ var parsed = {
+ prefix: match[1],
+ command: match[2]
+ };
+
+ var params = match[3].match(/(.*?) ?:(.*)/);
+ if (params) {
+ // Params before :
+ params[1] = (params[1])
+ ? params[1].split(' ')
+ : [];
+ // Rest after :
+ params[2] = params[2]
+ ? [params[2]]
+ : [];
+
+ params = params[1].concat(params[2]);
+ } else {
+ params = match[3].split(' ');
+ }
+
+ parsed.params = params;
+ return parsed;
+};
+
+Client.prototype.onConnect = function() {
+ this.send('NICK', this.nick);
+ this.send('USER', this.user, '0', '*', ':'+this.real);
+};
+
+Client.prototype.onReceive = function(chunk) {
+ this.buffer = this.buffer + chunk;
+
+ while (this.buffer) {
+ var offset = this.buffer.indexOf("\r\n");
+ if (offset < 0) {
+ return;
+ }
+
+ var message = this.buffer.substr(0, offset);
+ this.buffer = this.buffer.substr(offset + 2);
+ sys.puts('< '+message);
+
+ message = this.parse(message);
+
+ this.emit.apply(this, [message.command, message.prefix].concat(message.params));
+
+ if (message !== false) {
+ this.onMessage(message);
+ }
+ }
+};
+
+Client.prototype.onMessage = function(message) {
+ switch (message.command) {
+ case 'PING':
+ this.send('PONG', ':'+message.params[0]);
+ break;
+ }
+};
+
+Client.prototype.onEof = function() {
+ this.disconnect('eof');
+};
+
+Client.prototype.onTimeout = function() {
+ this.disconnect('timeout');
+};
+
+Client.prototype.onClose = function() {
+ this.disconnect('close');
+};
+
+exports.user = function(prefix) {
+ return prefix.match(/:([^!]+)!/)[1]
+};
View
10 node_modules/socket.io/examples/irc-output/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "socket.io-irc"
+ , "version": "0.0.1"
+ , "dependencies": {
+ "express": "2.5.5"
+ , "jade": "0.16.4"
+ , "stylus": "0.19.0"
+ , "nib": "0.2.0"
+ }
+}
View
69 node_modules/socket.io/examples/irc-output/public/stylesheets/style.styl
@@ -0,0 +1,69 @@
+@import 'nib'
+
+h2
+ font bold 18px Helvetica Neue, Arial
+
+#irc, #messages
+ width 600px
+
+#irc
+ position relative
+ border 1px solid #ccc
+
+#connecting
+ position absolute
+ height 410px
+ z-index 100
+ left 0
+ top 0
+ background #fff
+ text-align center
+ width 600px
+ font 15px Georgia
+ color #666
+ display block
+ .wrap
+ padding-top 150px
+
+.connected
+ #connecting
+ display none
+
+#messages
+ height 380px
+ background #eee
+ overflow auto
+ overflow-x hidden
+ overflow-y auto
+ &::-webkit-scrollbar
+ width 6px
+ height 6px
+ &::-webkit-scrollbar-button:start:decrement, ::-webkit-scrollbar-button:end:increment
+ display block
+ height 10px
+ &::-webkit-scrollbar-button:vertical:increment
+ background-color #fff
+ &::-webkit-scrollbar-track-piece
+ background-color #fff
+ -webkit-border-radius 3px
+ &::-webkit-scrollbar-thumb:vertical
+ height 50px
+ background-color #ccc
+ -webkit-border-radius 3px
+ &::-webkit-scrollbar-thumb:horizontal
+ width 50px
+ background-color #fff
+ -webkit-border-radius 3px
+ em
+ text-shadow 0 1px 0 #fff
+ color #999
+ p
+ padding 0
+ margin 0
+ font 12px Helvetica, Arial
+ padding 5px 10px
+ b
+ display inline-block
+ padding-right 10px
+ p:nth-child(even)
+ background #fafafa
View
8 node_modules/socket.io/index.js
@@ -0,0 +1,8 @@
+
+/*!
+ * socket.io-node
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
+ * MIT Licensed
+ */
+
+module.exports = require('./lib/socket.io');
View
97 node_modules/socket.io/lib/logger.js
@@ -0,0 +1,97 @@
+
+/*!
+ * socket.io-node
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var util = require('./util')
+ , toArray = util.toArray;
+
+/**
+ * Log levels.
+ */
+
+var levels = [
+ 'error'
+ , 'warn'
+ , 'info'
+ , 'debug'
+];
+
+/**
+ * Colors for log levels.
+ */
+
+var colors = [
+ 31
+ , 33
+ , 36
+ , 90
+];
+
+/**
+ * Pads the nice output to the longest log level.
+ */
+
+function pad (str) {
+ var max = 0;
+
+ for (var i = 0, l = levels.length; i < l; i++)
+ max = Math.max(max, levels[i].length);
+
+ if (str.length < max)
+ return str + new Array(max - str.length + 1).join(' ');
+
+ return str;
+};
+
+/**
+ * Logger (console).
+ *
+ * @api public
+ */
+
+var Logger = module.exports = function (opts) {
+ opts = opts || {}
+ this.colors = false !== opts.colors;
+ this.level = 3;
+ this.enabled = true;
+};
+
+/**
+ * Log method.
+ *
+ * @api public
+ */
+
+Logger.prototype.log = function (type) {
+ var index = levels.indexOf(type);
+
+ if (index > this.level || !this.enabled)
+ return this;
+
+ console.log.apply(
+ console
+ , [this.colors
+ ? ' \033[' + colors[index] + 'm' + pad(type) + ' -\033[39m'
+ : type + ':'
+ ].concat(toArray(arguments).slice(1))
+ );
+
+ return this;
+};
+
+/**
+ * Generate methods.
+ */
+
+levels.forEach(function (name) {
+ Logger.prototype[name] = function () {
+ this.log.apply(this, [name].concat(toArray(arguments)));
+ };
+});
View
977 node_modules/socket.io/lib/manager.js
@@ -0,0 +1,977 @@
+/*!
+ * socket.io-node
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var fs = require('fs')
+ , url = require('url')
+ , tty = require('tty')
+ , util = require('./util')
+ , store = require('./store')
+ , client = require('socket.io-client')
+ , transports = require('./transports')
+ , Logger = require('./logger')
+ , Socket = require('./socket')
+ , MemoryStore = require('./stores/memory')
+ , SocketNamespace = require('./namespace')
+ , Static = require('./static')
+ , EventEmitter = process.EventEmitter;
+
+/**
+ * Export the constructor.
+ */
+
+exports = module.exports = Manager;
+
+/**
+ * Default transports.
+ */
+
+var defaultTransports = exports.defaultTransports = [
+ 'websocket'
+ , 'htmlfile'
+ , 'xhr-polling'
+ , 'jsonp-polling'
+];
+
+/**
+ * Inherited defaults.
+ */
+
+var parent = module.parent.exports
+ , protocol = parent.protocol;
+
+/**
+ * Manager constructor.
+ *
+ * @param {HTTPServer} server
+ * @param {Object} options, optional
+ * @api public
+ */
+
+function Manager (server, options) {
+ this.server = server;
+ this.namespaces = {};
+ this.sockets = this.of('');
+ this.settings = {
+ origins: '*:*'
+ , log: true
+ , store: new MemoryStore
+ , logger: new Logger
+ , static: new Static(this)
+ , heartbeats: true
+ , resource: '/socket.io'
+ , transports: defaultTransports
+ , authorization: false
+ , blacklist: ['disconnect']
+ , 'log level': 3
+ , 'log colors': tty.isatty(process.stdout.fd)
+ , 'close timeout': 25
+ , 'heartbeat timeout': 15
+ , 'heartbeat interval': 20
+ , 'polling duration': 20
+ , 'flash policy server': true
+ , 'flash policy port': 10843
+ , 'destroy upgrade': true
+ , 'destroy buffer size': 10E7
+ , 'browser client': true
+ , 'browser client cache': true
+ , 'browser client minification': false
+ , 'browser client etag': false
+ , 'browser client expires': 315360000
+ , 'browser client gzip': false
+ , 'browser client handler': false
+ , 'client store expiration': 15
+ , 'match origin protocol': false
+ };
+
+ for (var i in options) {
+ this.settings[i] = options[i];
+ }
+
+ var self = this;
+
+ // default error handler
+ server.on('error', function(err) {
+ self.log.warn('error raised: ' + err);
+ });
+
+ this.initStore();
+
+ this.on('set:store', function() {
+ self.initStore();
+ });
+
+ // reset listeners
+ this.oldListeners = server.listeners('request');