Browse Source

Initial commit

dev_h
Ophir LOJKINE 11 years ago
parent
commit
778b3afd33
100 changed files with 12056 additions and 0 deletions
  1. 1
    0
      AUTHORS
  2. 130
    0
      index.html
  3. 3
    0
      node_modules/socket.io/.npmignore
  4. 6
    0
      node_modules/socket.io/.travis.yml
  5. 325
    0
      node_modules/socket.io/History.md
  6. 22
    0
      node_modules/socket.io/LICENSE
  7. 31
    0
      node_modules/socket.io/Makefile
  8. 364
    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. 8
    0
      node_modules/socket.io/index.js
  13. 97
    0
      node_modules/socket.io/lib/logger.js
  14. 1027
    0
      node_modules/socket.io/lib/manager.js
  15. 355
    0
      node_modules/socket.io/lib/namespace.js
  16. 249
    0
      node_modules/socket.io/lib/parser.js
  17. 143
    0
      node_modules/socket.io/lib/socket.io.js
  18. 369
    0
      node_modules/socket.io/lib/socket.js
  19. 395
    0
      node_modules/socket.io/lib/static.js
  20. 98
    0
      node_modules/socket.io/lib/store.js
  21. 143
    0
      node_modules/socket.io/lib/stores/memory.js
  22. 269
    0
      node_modules/socket.io/lib/stores/redis.js
  23. 534
    0
      node_modules/socket.io/lib/transport.js
  24. 129
    0
      node_modules/socket.io/lib/transports/flashsocket.js
  25. 83
    0
      node_modules/socket.io/lib/transports/htmlfile.js
  26. 147
    0
      node_modules/socket.io/lib/transports/http-polling.js
  27. 121
    0
      node_modules/socket.io/lib/transports/http.js
  28. 12
    0
      node_modules/socket.io/lib/transports/index.js
  29. 97
    0
      node_modules/socket.io/lib/transports/jsonp-polling.js
  30. 36
    0
      node_modules/socket.io/lib/transports/websocket.js
  31. 362
    0
      node_modules/socket.io/lib/transports/websocket/default.js
  32. 622
    0
      node_modules/socket.io/lib/transports/websocket/hybi-07-12.js
  33. 622
    0
      node_modules/socket.io/lib/transports/websocket/hybi-16.js
  34. 11
    0
      node_modules/socket.io/lib/transports/websocket/index.js
  35. 69
    0
      node_modules/socket.io/lib/transports/xhr-polling.js
  36. 50
    0
      node_modules/socket.io/lib/util.js
  37. 3
    0
      node_modules/socket.io/node_modules/base64id/.npmignore
  38. 18
    0
      node_modules/socket.io/node_modules/base64id/README.md
  39. 103
    0
      node_modules/socket.io/node_modules/base64id/lib/base64id.js
  40. 29
    0
      node_modules/socket.io/node_modules/base64id/package.json
  41. 1
    0
      node_modules/socket.io/node_modules/policyfile/.npmignore
  42. 19
    0
      node_modules/socket.io/node_modules/policyfile/LICENSE
  43. 7
    0
      node_modules/socket.io/node_modules/policyfile/Makefile
  44. 98
    0
      node_modules/socket.io/node_modules/policyfile/README.md
  45. 375
    0
      node_modules/socket.io/node_modules/policyfile/doc/index.html
  46. 8
    0
      node_modules/socket.io/node_modules/policyfile/examples/basic.fallback.js
  47. 5
    0
      node_modules/socket.io/node_modules/policyfile/examples/basic.js
  48. 1
    0
      node_modules/socket.io/node_modules/policyfile/index.js
  49. 289
    0
      node_modules/socket.io/node_modules/policyfile/lib/server.js
  50. 55
    0
      node_modules/socket.io/node_modules/policyfile/package.json
  51. 21
    0
      node_modules/socket.io/node_modules/policyfile/tests/ssl/ssl.crt
  52. 27
    0
      node_modules/socket.io/node_modules/policyfile/tests/ssl/ssl.private.key
  53. 231
    0
      node_modules/socket.io/node_modules/policyfile/tests/unit.test.js
  54. 1
    0
      node_modules/socket.io/node_modules/redis/.npmignore
  55. 691
    0
      node_modules/socket.io/node_modules/redis/README.md
  56. 89
    0
      node_modules/socket.io/node_modules/redis/benches/buffer_bench.js
  57. 38
    0
      node_modules/socket.io/node_modules/redis/benches/hiredis_parser.js
  58. 14
    0
      node_modules/socket.io/node_modules/redis/benches/re_sub_test.js
  59. 29
    0
      node_modules/socket.io/node_modules/redis/benches/reconnect_test.js
  60. 16
    0
      node_modules/socket.io/node_modules/redis/benches/stress/codec.js
  61. 38
    0
      node_modules/socket.io/node_modules/redis/benches/stress/pubsub/pub.js
  62. 10
    0
      node_modules/socket.io/node_modules/redis/benches/stress/pubsub/run
  63. 23
    0
      node_modules/socket.io/node_modules/redis/benches/stress/pubsub/server.js
  64. 49
    0
      node_modules/socket.io/node_modules/redis/benches/stress/rpushblpop/pub.js
  65. 6
    0
      node_modules/socket.io/node_modules/redis/benches/stress/rpushblpop/run
  66. 30
    0
      node_modules/socket.io/node_modules/redis/benches/stress/rpushblpop/server.js
  67. 13
    0
      node_modules/socket.io/node_modules/redis/benches/stress/speed/00
  68. 13
    0
      node_modules/socket.io/node_modules/redis/benches/stress/speed/plot
  69. BIN
      node_modules/socket.io/node_modules/redis/benches/stress/speed/size-rate.png
  70. 84
    0
      node_modules/socket.io/node_modules/redis/benches/stress/speed/speed.js
  71. 18
    0
      node_modules/socket.io/node_modules/redis/benches/sub_quit_test.js
  72. 219
    0
      node_modules/socket.io/node_modules/redis/changelog.md
  73. 87
    0
      node_modules/socket.io/node_modules/redis/diff_multi_bench_output.js
  74. 5
    0
      node_modules/socket.io/node_modules/redis/examples/auth.js
  75. 33
    0
      node_modules/socket.io/node_modules/redis/examples/backpressure_drain.js
  76. 9
    0
      node_modules/socket.io/node_modules/redis/examples/eval.js
  77. 24
    0
      node_modules/socket.io/node_modules/redis/examples/extend.js
  78. 32
    0
      node_modules/socket.io/node_modules/redis/examples/file.js
  79. 5
    0
      node_modules/socket.io/node_modules/redis/examples/mget.js
  80. 10
    0
      node_modules/socket.io/node_modules/redis/examples/monitor.js
  81. 46
    0
      node_modules/socket.io/node_modules/redis/examples/multi.js
  82. 29
    0
      node_modules/socket.io/node_modules/redis/examples/multi2.js
  83. 33
    0
      node_modules/socket.io/node_modules/redis/examples/psubscribe.js
  84. 41
    0
      node_modules/socket.io/node_modules/redis/examples/pub_sub.js
  85. 24
    0
      node_modules/socket.io/node_modules/redis/examples/simple.js
  86. 17
    0
      node_modules/socket.io/node_modules/redis/examples/sort.js
  87. 15
    0
      node_modules/socket.io/node_modules/redis/examples/subqueries.js
  88. 19
    0
      node_modules/socket.io/node_modules/redis/examples/subquery.js
  89. 29
    0
      node_modules/socket.io/node_modules/redis/examples/unix_socket.js
  90. 31
    0
      node_modules/socket.io/node_modules/redis/examples/web_server.js
  91. 39
    0
      node_modules/socket.io/node_modules/redis/generate_commands.js
  92. 1113
    0
      node_modules/socket.io/node_modules/redis/index.js
  93. 147
    0
      node_modules/socket.io/node_modules/redis/lib/commands.js
  94. 46
    0
      node_modules/socket.io/node_modules/redis/lib/parser/hiredis.js
  95. 317
    0
      node_modules/socket.io/node_modules/redis/lib/parser/javascript.js
  96. 61
    0
      node_modules/socket.io/node_modules/redis/lib/queue.js
  97. 12
    0
      node_modules/socket.io/node_modules/redis/lib/to_array.js
  98. 11
    0
      node_modules/socket.io/node_modules/redis/lib/util.js
  99. 11
    0
      node_modules/socket.io/node_modules/redis/mem.js
  100. 0
    0
      node_modules/socket.io/node_modules/redis/multi_bench.js

+ 1
- 0
AUTHORS View File

@@ -0,0 +1 @@
1
+Ophir LOJKINE (ophir.lojkine@free.fr)

+ 130
- 0
index.html View File

@@ -0,0 +1,130 @@
1
+<!DOCTYPE html>
2
+<html>
3
+
4
+<head>
5
+	<meta charset="utf-8" />
6
+	<script src="/socket.io/socket.io.js"></script>
7
+	<style type="text/css">
8
+		html, body, svg {
9
+			padding:0;
10
+			margin:0;
11
+		}
12
+	</style>
13
+</head>
14
+
15
+<body>
16
+
17
+<svg id="canvas"
18
+	width="500" height="500" version="1.1"
19
+     xmlns="http://www.w3.org/2000/svg">
20
+    <defs>
21
+	<style type="text/css"><![CDATA[
22
+      polyline {
23
+        fill: none;
24
+        stroke: black;
25
+        stroke-width: 3;
26
+      }
27
+    ]]></style>
28
+    </defs>
29
+</svg>
30
+
31
+
32
+<script>
33
+var socket = io.connect('');
34
+
35
+socket.on('broadcast', function (data) {
36
+	switch(data.type) {
37
+		case "newLine":
38
+			createLine(data.id);
39
+			break;
40
+		case "point":		
41
+			var line = svg.getElementById(data.line);
42
+			if (!line) {
43
+				throw "Hmmm... I received a point of a line I don't know...";
44
+			}
45
+			addPoint(line, data.x, data.y);
46
+			break;
47
+	}
48
+});
49
+
50
+
51
+var svg = document.getElementById("canvas");
52
+	curLine = null;
53
+
54
+svg.width.baseVal.value = document.body.clientWidth;
55
+svg.height.baseVal.value = document.body.clientHeight;
56
+
57
+var lastTime = performance.now();
58
+
59
+function pressHandler (ev) {
60
+	curLine = createLine();
61
+	socket.emit('broadcast', {
62
+		'type' : 'newLine',
63
+		'id' : curLine.id
64
+	});
65
+	ev.preventDefault();
66
+	return false;
67
+}
68
+svg.addEventListener("mousedown", pressHandler);
69
+//svg.addEventListener("touchstart", pressHandler);
70
+
71
+function moveHandler (ev){
72
+	if (curLine !== null &&
73
+		performance.now() - lastTime > 50) {
74
+		var x = ev.clientX + window.scrollX;
75
+			y = ev.clientY + window.scrollY;
76
+		socket.emit('broadcast', {
77
+			'type' : 'point',
78
+			'line' : curLine.id,
79
+			'x' : x,
80
+			'y' : y
81
+		});
82
+		addPoint(curLine, x,y);
83
+		lastTime = performance.now();
84
+	}
85
+	ev.preventDefault();
86
+	return false;
87
+}
88
+svg.addEventListener("mousemove", moveHandler);
89
+//svg.addEventListener("touchmove", moveHandler);
90
+
91
+function releaseHandler (){
92
+	curLine = null;
93
+	return false;
94
+}
95
+svg.addEventListener("mouseup", releaseHandler);
96
+svg.addEventListener("mouseleave", releaseHandler);
97
+//svg.addEventListener("touchend", releaseHandler);
98
+
99
+
100
+function addPoint (line, x,y) {
101
+	var point = svg.createSVGPoint();
102
+	point.x = x; point.y = y;
103
+
104
+	line.points.appendItem(point);
105
+
106
+	if (x > svg.width.baseVal.value - 100) {
107
+		svg.width.baseVal.value = x + 1000;
108
+	}
109
+	if (y > svg.height.baseVal.value - 100) {
110
+		svg.height.baseVal.value = y + 1000;
111
+	}
112
+}
113
+
114
+function createLine(id) {
115
+	var line = document.createElementNS(svg.namespaceURI, "polyline");
116
+	if (!id) id = generateUID("line");
117
+	line.id = id;
118
+	svg.appendChild(line);
119
+	return line;
120
+}
121
+
122
+function generateUID(prefix, suffix) {
123
+	var rndStr = (Math.round(Math.random()*1e19)).toString(36);
124
+	if (prefix) rndStr = prefix + rndStr;
125
+	if (suffix) rndStr = rndStr + suffix;
126
+	return rndStr;
127
+}
128
+</script>
129
+</body>
130
+</html>

+ 3
- 0
node_modules/socket.io/.npmignore View File

@@ -0,0 +1,3 @@
1
+support
2
+test
3
+examples

+ 6
- 0
node_modules/socket.io/.travis.yml View File

@@ -0,0 +1,6 @@
1
+language: node_js
2
+node_js:
3
+  - 0.6
4
+
5
+notifications:
6
+  irc: "irc.freenode.org#socket.io"

+ 325
- 0
node_modules/socket.io/History.md View File

@@ -0,0 +1,325 @@
1
+
2
+0.9.16 / 2013-06-06
3
+===================
4
+
5
+  * transports: added tests for htmlfile escaping/unescaping
6
+
7
+0.9.15 / 2013-06-06
8
+===================
9
+
10
+  * transports: added escaping to htmlfile (fixes #1251)
11
+
12
+0.9.14 / 2013-03-29
13
+===================
14
+
15
+  * manager: fix memory leak with SSL [jpallen]
16
+
17
+0.9.13 / 2012-12-13
18
+===================
19
+
20
+  * package: fixed `base64id` requirement
21
+
22
+0.9.12 / 2012-12-13
23
+===================
24
+
25
+  * manager: fix for latest node which is returning a clone with `listeners` [viirya]
26
+
27
+0.9.11 / 2012-11-02
28
+===================
29
+
30
+  * package: move redis to optionalDependenices [3rd-Eden]
31
+  * bumped client
32
+
33
+0.9.10 / 2012-08-10
34
+===================
35
+
36
+  * Don't lowercase log messages
37
+  * Always set the HTTP response in case an error should be returned to the client
38
+  * Create or destroy the flash policy server on configuration change
39
+  * Honour configuration to disable flash policy server
40
+  * Add express 3.0 instructions on Readme.md
41
+  * Bump client
42
+
43
+0.9.9 / 2012-08-01
44
+==================
45
+
46
+  * Fixed sync disconnect xhrs handling
47
+  * Put license text in its own file (#965)
48
+  * Add warning to .listen() to ease the migration to Express 3.x
49
+  * Restored compatibility with node 0.4.x
50
+
51
+0.9.8 / 2012-07-24
52
+==================
53
+
54
+  * Bumped client.
55
+
56
+0.9.7 / 2012-07-24
57
+==================
58
+
59
+  * Prevent crash when socket leaves a room twice.
60
+  * Corrects unsafe usage of for..in
61
+  * Fix for node 0.8 with `gzip compression` [vadimi]
62
+  * Update redis to support Node 0.8.x
63
+  * Made ID generation securely random
64
+  * Fix Redis Store race condition in manager onOpen unsubscribe callback
65
+  * Fix for EventEmitters always reusing the same Array instance for listeners
66
+
67
+0.9.6 / 2012-04-17
68
+==================
69
+
70
+  * Fixed XSS in jsonp-polling.
71
+
72
+0.9.5 / 2012-04-05
73
+==================
74
+
75
+  * Added test for polling and socket close.
76
+  * Ensure close upon request close.
77
+  * Fix disconnection reason being lost for polling transports.
78
+  * Ensure that polling transports work with Connection: close.
79
+  * Log disconnection reason.
80
+
81
+0.9.4 / 2012-04-01
82
+==================
83
+
84
+  * Disconnecting from namespace improvement (#795) [DanielBaulig]
85
+  * Bumped client with polling reconnection loop (#438)
86
+
87
+0.9.3 / 2012-03-28
88
+==================
89
+
90
+  * Fix "Syntax error" on FF Web Console with XHR Polling [mikito]
91
+
92
+0.9.2 / 2012-03-13
93
+==================
94
+
95
+  * More sensible close `timeout default` (fixes disconnect issue)
96
+
97
+0.9.1-1 / 2012-03-02
98
+====================
99
+
100
+  * Bumped client with NPM dependency fix.
101
+
102
+0.9.1 / 2012-03-02
103
+==================
104
+
105
+  * Changed heartbeat timeout and interval defaults (60 and 25 seconds)
106
+  * Make tests work both on 0.4 and 0.6
107
+  * Updated client (improvements + bug fixes).
108
+
109
+0.9.0 / 2012-02-26
110
+==================
111
+
112
+  * Make it possible to use a regexp to match the socket.io resource URL.
113
+    We need this because we have to prefix the socket.io URL with a variable ID.
114
+  * Supplemental fix to gavinuhma/authfix, it looks like the same Access-Control-Origin logic is needed in the http and xhr-polling transports
115
+  * Updated express dep for windows compatibility.
116
+  * Combine two substr calls into one in decodePayload to improve performance
117
+  * Minor documentation fix
118
+  * Minor. Conform to style of other files.
119
+  * Switching setting to 'match origin protocol'
120
+  * Revert "Fixes leaking Redis subscriptions for #663. The local flag was not getting passed through onClientDisconnect()."
121
+  * Revert "Handle leaked dispatch:[id] subscription."
122
+  * Merge pull request #667 from dshaw/patch/redis-disconnect
123
+  * Handle leaked dispatch:[id] subscription.
124
+  * Fixes leaking Redis subscriptions for #663. The local flag was not getting passed through onClientDisconnect().
125
+  * Prevent memory leaking on uncompleted requests & add max post size limitation
126
+  * Fix for testcase
127
+  * Set Access-Control-Allow-Credentials true, regardless of cookie
128
+  * Remove assertvarnish from package as it breaks on 0.6
129
+  * Correct irc channel
130
+  * Added proper return after reserved field error
131
+  * Fixes manager.js failure to close connection after transport error has happened
132
+  * Added implicit port 80 for origin checks. fixes #638
133
+  * Fixed bug #432 in 0.8.7
134
+  * Set Access-Control-Allow-Origin header to origin to enable withCredentials
135
+  * Adding configuration variable matchOriginProtocol
136
+  * Fixes location mismatch error in Safari.
137
+  * Use tty to detect if we should add colors or not by default.
138
+  * Updated the package location.
139
+
140
+0.8.7 / 2011-11-05
141
+==================
142
+
143
+  * Fixed memory leaks in closed clients.
144
+  * Fixed memory leaks in namespaces.
145
+  * Fixed websocket handling for malformed requests from proxies. [einaros]
146
+  * Node 0.6 compatibility. [einaros] [3rd-Eden]
147
+  * Adapted tests and examples.
148
+
149
+0.8.6 / 2011-10-27 
150
+==================
151
+
152
+  * Added JSON decoding on jsonp-polling transport.
153
+  * Fixed README example.
154
+  * Major speed optimizations [3rd-Eden] [einaros] [visionmedia]
155
+  * Added decode/encode benchmarks [visionmedia]
156
+  * Added support for black-listing client sent events.
157
+  * Fixed logging options, closes #540 [3rd-Eden]
158
+  * Added vary header for gzip [3rd-Eden]
159
+  * Properly cleaned up async websocket / flashsocket tests, after patching node-websocket-client
160
+  * Patched to properly shut down when a finishClose call is made during connection establishment
161
+  * Added support for socket.io version on url and far-future Expires [3rd-Eden] [getify]
162
+  * Began IE10 compatibility [einaros] [tbranyen]
163
+  * Misc WebSocket fixes [einaros]
164
+  * Added UTF8 to respone headers for htmlfile [3rd-Eden]
165
+
166
+0.8.5 / 2011-10-07
167
+==================
168
+
169
+  * Added websocket draft HyBi-16 support. [einaros]
170
+  * Fixed websocket continuation bugs. [einaros]
171
+  * Fixed flashsocket transport name.
172
+  * Fixed websocket tests.
173
+  * Ensured `parser#decodePayload` doesn't choke.
174
+  * Added http referrer verification to manager verifyOrigin.
175
+  * Added access control for cross domain xhr handshakes [3rd-Eden]
176
+  * Added support for automatic generation of socket.io files [3rd-Eden]
177
+  * Added websocket binary support [einaros]
178
+  * Added gzip support for socket.io.js [3rd-Eden]
179
+  * Expose socket.transport [3rd-Eden]
180
+  * Updated client.
181
+
182
+0.8.4 / 2011-09-06
183
+==================
184
+
185
+  * Client build
186
+
187
+0.8.3 / 2011-09-03
188
+==================
189
+
190
+  * Fixed `\n` parsing for non-JSON packets (fixes #479).
191
+  * Fixed parsing of certain unicode characters (fixes #451).
192
+  * Fixed transport message packet logging.
193
+  * Fixed emission of `error` event resulting in an uncaught exception if unhandled (fixes #476).
194
+  * Fixed; allow for falsy values as the configuration value of `log level` (fixes #491).
195
+  * Fixed repository URI in `package.json`. Fixes #504.
196
+  * Added text/plain content-type to handshake responses [einaros]
197
+  * Improved single byte writes [einaros]
198
+  * Updated socket.io-flashsocket default port from 843 to 10843 [3rd-Eden]
199
+  * Updated client.
200
+
201
+0.8.2 / 2011-08-29
202
+==================
203
+
204
+  * Updated client.
205
+
206
+0.8.1 / 2011-08-29
207
+==================
208
+
209
+  * Fixed utf8 bug in send framing in websocket [einaros]
210
+  * Fixed typo in docs [Znarkus]
211
+  * Fixed bug in send framing for over 64kB of data in websocket [einaros]
212
+  * Corrected ping handling in websocket transport [einaros]
213
+
214
+0.8.0 / 2011-08-28
215
+==================
216
+
217
+  * Updated to work with two-level websocket versioning. [einaros]
218
+  * Added hybi07 support. [einaros]
219
+  * Added hybi10 support. [einaros]
220
+  * Added http referrer verification to manager.js verifyOrigin. [einaors]
221
+
222
+0.7.11 / 2011-08-27
223
+===================
224
+
225
+  * Updated socket.io-client.
226
+
227
+0.7.10 / 2011-08-27
228
+===================
229
+
230
+  * Updated socket.io-client.
231
+
232
+0.7.9 / 2011-08-12
233
+==================
234
+
235
+  * Updated socket.io-client.
236
+  * Make sure we only do garbage collection when the server we receive is actually run.
237
+
238
+0.7.8 / 2011-08-08
239
+==================
240
+
241
+  * Changed; make sure sio#listen passes options to both HTTP server and socket.io manager.
242
+  * Added docs for sio#listen.
243
+  * Added options parameter support for Manager constructor.
244
+  * Added memory leaks tests and test-leaks Makefile task.
245
+  * Removed auto npm-linking from make test.
246
+  * Make sure that you can disable heartbeats. [3rd-Eden]
247
+  * Fixed rooms memory leak [3rd-Eden]
248
+  * Send response once we got all POST data, not immediately [Pita]
249
+  * Fixed onLeave behavior with missing clientsk [3rd-Eden]
250
+  * Prevent duplicate references in rooms.
251
+  * Added alias for `to` to `in` and `in` to `to`.
252
+  * Fixed roomClients definition.
253
+  * Removed dependency on redis for installation without npm [3rd-Eden]
254
+  * Expose path and querystring in handshakeData [3rd-Eden]
255
+
256
+0.7.7 / 2011-07-12
257
+==================
258
+
259
+  * Fixed double dispatch handling with emit to closed clients.
260
+  * Added test for emitting to closed clients to prevent regression.
261
+  * Fixed race condition in redis test.
262
+  * Changed Transport#end instrumentation.
263
+  * Leveraged $emit instead of emit internally.
264
+  * Made tests faster.
265
+  * Fixed double disconnect events.
266
+  * Fixed disconnect logic
267
+  * Simplified remote events handling in Socket.
268
+  * Increased testcase timeout.
269
+  * Fixed unknown room emitting (GH-291). [3rd-Eden]
270
+  * Fixed `address` in handshakeData. [3rd-Eden]
271
+  * Removed transports definition in chat example.
272
+  * Fixed room cleanup
273
+  * Fixed; make sure the client is cleaned up after booting.
274
+  * Make sure to mark the client as non-open if the connection is closed.
275
+  * Removed unneeded `buffer` declarations.
276
+  * Fixed; make sure to clear socket handlers and subscriptions upon transport close.
277
+
278
+0.7.6 / 2011-06-30
279
+==================
280
+
281
+  * Fixed general dispatching when a client has closed.
282
+
283
+0.7.5 / 2011-06-30
284
+==================
285
+
286
+  * Fixed dispatching to clients that are disconnected.
287
+
288
+0.7.4 / 2011-06-30
289
+==================
290
+
291
+  * Fixed; only clear handlers if they were set. [level09]
292
+
293
+0.7.3 / 2011-06-30
294
+==================
295
+
296
+  * Exposed handshake data to clients.
297
+  * Refactored dispatcher interface.
298
+  * Changed; Moved id generation method into the manager.
299
+  * Added sub-namespace authorization. [3rd-Eden]
300
+  * Changed; normalized SocketNamespace local eventing [dvv]
301
+  * Changed; Use packet.reason or default to 'packet' [3rd-Eden]
302
+  * Changed console.error to console.log.
303
+  * Fixed; bind both servers at the same time do that the test never times out.
304
+  * Added 304 support.
305
+  * Removed `Transport#name` for abstract interface.
306
+  * Changed; lazily require http and https module only when needed. [3rd-Eden]
307
+
308
+0.7.2 / 2011-06-22
309
+==================
310
+
311
+  * Make sure to write a packet (of type `noop`) when closing a poll.
312
+    This solves a problem with cross-domain requests being flagged as aborted and
313
+    reconnection being triggered.
314
+  * Added `noop` message type.
315
+
316
+0.7.1 / 2011-06-21 
317
+==================
318
+
319
+  * Fixed cross-domain XHR.
320
+  * Added CORS test to xhr-polling suite.
321
+
322
+0.7.0 / 2010-06-21
323
+==================
324
+
325
+  * http://socket.io/announcement.html

+ 22
- 0
node_modules/socket.io/LICENSE View File

@@ -0,0 +1,22 @@
1
+(The MIT License)
2
+
3
+Copyright (c) 2011 Guillermo Rauch <guillermo@learnboost.com>
4
+
5
+Permission is hereby granted, free of charge, to any person obtaining
6
+a copy of this software and associated documentation files (the
7
+'Software'), to deal in the Software without restriction, including
8
+without limitation the rights to use, copy, modify, merge, publish,
9
+distribute, sublicense, and/or sell copies of the Software, and to
10
+permit persons to whom the Software is furnished to do so, subject to
11
+the following conditions:
12
+
13
+The above copyright notice and this permission notice shall be
14
+included in all copies or substantial portions of the Software.
15
+
16
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 31
- 0
node_modules/socket.io/Makefile View File

@@ -0,0 +1,31 @@
1
+
2
+ALL_TESTS = $(shell find test/ -name '*.test.js')
3
+ALL_BENCH = $(shell find benchmarks -name '*.bench.js')
4
+
5
+run-tests:
6
+	@./node_modules/.bin/expresso \
7
+		-t 3000 \
8
+		-I support \
9
+		--serial \
10
+		$(TESTFLAGS) \
11
+		$(TESTS)
12
+
13
+test:
14
+	@$(MAKE) NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests
15
+
16
+test-cov:
17
+	@TESTFLAGS=--cov $(MAKE) test
18
+
19
+test-leaks:
20
+	@ls test/leaks/* | xargs node --expose_debug_as=debug --expose_gc
21
+
22
+run-bench:
23
+	@node $(PROFILEFLAGS) benchmarks/runner.js
24
+
25
+bench:
26
+	@$(MAKE) BENCHMARKS="$(ALL_BENCH)" run-bench
27
+
28
+profile:
29
+	@PROFILEFLAGS='--prof --trace-opt --trace-bailout --trace-deopt' $(MAKE) bench
30
+
31
+.PHONY: test bench profile

+ 364
- 0
node_modules/socket.io/Readme.md View File

@@ -0,0 +1,364 @@
1
+# Socket.IO
2
+
3
+Socket.IO is a Node.JS project that makes WebSockets and realtime possible in
4
+all browsers. It also enhances WebSockets by providing built-in multiplexing,
5
+horizontal scalability, automatic JSON encoding/decoding, and more.
6
+
7
+## How to Install
8
+
9
+```bash
10
+npm install socket.io
11
+```
12
+
13
+## How to use
14
+
15
+First, require `socket.io`:
16
+
17
+```js
18
+var io = require('socket.io');
19
+```
20
+
21
+Next, attach it to a HTTP/HTTPS server. If you're using the fantastic `express`
22
+web framework:
23
+
24
+#### Express 3.x
25
+
26
+```js
27
+var app = express()
28
+  , server = require('http').createServer(app)
29
+  , io = io.listen(server);
30
+
31
+server.listen(80);
32
+
33
+io.sockets.on('connection', function (socket) {
34
+  socket.emit('news', { hello: 'world' });
35
+  socket.on('my other event', function (data) {
36
+    console.log(data);
37
+  });
38
+});
39
+```
40
+
41
+#### Express 2.x
42
+
43
+```js
44
+var app = express.createServer()
45
+  , io = io.listen(app);
46
+
47
+app.listen(80);
48
+
49
+io.sockets.on('connection', function (socket) {
50
+  socket.emit('news', { hello: 'world' });
51
+  socket.on('my other event', function (data) {
52
+    console.log(data);
53
+  });
54
+});
55
+```
56
+
57
+Finally, load it from the client side code:
58
+
59
+```html
60
+<script src="/socket.io/socket.io.js"></script>
61
+<script>
62
+  var socket = io.connect('http://localhost');
63
+  socket.on('news', function (data) {
64
+    console.log(data);
65
+    socket.emit('my other event', { my: 'data' });
66
+  });
67
+</script>
68
+```
69
+
70
+For more thorough examples, look at the `examples/` directory.
71
+
72
+## Short recipes
73
+
74
+### Sending and receiving events.
75
+
76
+Socket.IO allows you to emit and receive custom events.
77
+Besides `connect`, `message` and `disconnect`, you can emit custom events:
78
+
79
+```js
80
+// note, io.listen(<port>) will create a http server for you
81
+var io = require('socket.io').listen(80);
82
+
83
+io.sockets.on('connection', function (socket) {
84
+  io.sockets.emit('this', { will: 'be received by everyone' });
85
+
86
+  socket.on('private message', function (from, msg) {
87
+    console.log('I received a private message by ', from, ' saying ', msg);
88
+  });
89
+
90
+  socket.on('disconnect', function () {
91
+    io.sockets.emit('user disconnected');
92
+  });
93
+});
94
+```
95
+
96
+### Storing data associated to a client
97
+
98
+Sometimes it's necessary to store data associated with a client that's
99
+necessary for the duration of the session.
100
+
101
+#### Server side
102
+
103
+```js
104
+var io = require('socket.io').listen(80);
105
+
106
+io.sockets.on('connection', function (socket) {
107
+  socket.on('set nickname', function (name) {
108
+    socket.set('nickname', name, function () { socket.emit('ready'); });
109
+  });
110
+
111
+  socket.on('msg', function () {
112
+    socket.get('nickname', function (err, name) {
113
+      console.log('Chat message by ', name);
114
+    });
115
+  });
116
+});
117
+```
118
+
119
+#### Client side
120
+
121
+```html
122
+<script>
123
+  var socket = io.connect('http://localhost');
124
+
125
+  socket.on('connect', function () {
126
+    socket.emit('set nickname', prompt('What is your nickname?'));
127
+    socket.on('ready', function () {
128
+      console.log('Connected !');
129
+      socket.emit('msg', prompt('What is your message?'));
130
+    });
131
+  });
132
+</script>
133
+```
134
+
135
+### Restricting yourself to a namespace
136
+
137
+If you have control over all the messages and events emitted for a particular
138
+application, using the default `/` namespace works.
139
+
140
+If you want to leverage 3rd-party code, or produce code to share with others,
141
+socket.io provides a way of namespacing a `socket`.
142
+
143
+This has the benefit of `multiplexing` a single connection. Instead of
144
+socket.io using two `WebSocket` connections, it'll use one.
145
+
146
+The following example defines a socket that listens on '/chat' and one for
147
+'/news':
148
+
149
+#### Server side
150
+
151
+```js
152
+var io = require('socket.io').listen(80);
153
+
154
+var chat = io
155
+  .of('/chat')
156
+  .on('connection', function (socket) {
157
+    socket.emit('a message', { that: 'only', '/chat': 'will get' });
158
+    chat.emit('a message', { everyone: 'in', '/chat': 'will get' });
159
+  });
160
+
161
+var news = io
162
+  .of('/news');
163
+  .on('connection', function (socket) {
164
+    socket.emit('item', { news: 'item' });
165
+  });
166
+```
167
+
168
+#### Client side:
169
+
170
+```html
171
+<script>
172
+  var chat = io.connect('http://localhost/chat')
173
+    , news = io.connect('http://localhost/news');
174
+
175
+  chat.on('connect', function () {
176
+    chat.emit('hi!');
177
+  });
178
+
179
+  news.on('news', function () {
180
+    news.emit('woot');
181
+  });
182
+</script>
183
+```
184
+
185
+### Sending volatile messages.
186
+
187
+Sometimes certain messages can be dropped. Let's say you have an app that
188
+shows realtime tweets for the keyword `bieber`. 
189
+
190
+If a certain client is not ready to receive messages (because of network slowness
191
+or other issues, or because he's connected through long polling and is in the
192
+middle of a request-response cycle), if he doesn't receive ALL the tweets related
193
+to bieber your application won't suffer.
194
+
195
+In that case, you might want to send those messages as volatile messages.
196
+
197
+#### Server side
198
+
199
+```js
200
+var io = require('socket.io').listen(80);
201
+
202
+io.sockets.on('connection', function (socket) {
203
+  var tweets = setInterval(function () {
204
+    getBieberTweet(function (tweet) {
205
+      socket.volatile.emit('bieber tweet', tweet);
206
+    });
207
+  }, 100);
208
+
209
+  socket.on('disconnect', function () {
210
+    clearInterval(tweets);
211
+  });
212
+});
213
+```
214
+
215
+#### Client side
216
+
217
+In the client side, messages are received the same way whether they're volatile
218
+or not.
219
+
220
+### Getting acknowledgements
221
+
222
+Sometimes, you might want to get a callback when the client confirmed the message
223
+reception.
224
+
225
+To do this, simply pass a function as the last parameter of `.send` or `.emit`.
226
+What's more, when you use `.emit`, the acknowledgement is done by you, which
227
+means you can also pass data along:
228
+
229
+#### Server side
230
+
231
+```js
232
+var io = require('socket.io').listen(80);
233
+
234
+io.sockets.on('connection', function (socket) {
235
+  socket.on('ferret', function (name, fn) {
236
+    fn('woot');
237
+  });
238
+});
239
+```
240
+
241
+#### Client side
242
+
243
+```html
244
+<script>
245
+  var socket = io.connect(); // TIP: .connect with no args does auto-discovery
246
+  socket.on('connect', function () { // TIP: you can avoid listening on `connect` and listen on events directly too!
247
+    socket.emit('ferret', 'tobi', function (data) {
248
+      console.log(data); // data will be 'woot'
249
+    });
250
+  });
251
+</script>
252
+```
253
+
254
+### Broadcasting messages
255
+
256
+To broadcast, simply add a `broadcast` flag to `emit` and `send` method calls.
257
+Broadcasting means sending a message to everyone else except for the socket
258
+that starts it.
259
+
260
+#### Server side
261
+
262
+```js
263
+var io = require('socket.io').listen(80);
264
+
265
+io.sockets.on('connection', function (socket) {
266
+  socket.broadcast.emit('user connected');
267
+  socket.broadcast.json.send({ a: 'message' });
268
+});
269
+```
270
+
271
+### Rooms
272
+
273
+Sometimes you want to put certain sockets in the same room, so that it's easy
274
+to broadcast to all of them together.
275
+
276
+Think of this as built-in channels for sockets. Sockets `join` and `leave`
277
+rooms in each socket.
278
+
279
+#### Server side
280
+
281
+```js
282
+var io = require('socket.io').listen(80);
283
+
284
+io.sockets.on('connection', function (socket) {
285
+  socket.join('justin bieber fans');
286
+  socket.broadcast.to('justin bieber fans').emit('new fan');
287
+  io.sockets.in('rammstein fans').emit('new non-fan');
288
+});
289
+```
290
+
291
+### Using it just as a cross-browser WebSocket
292
+
293
+If you just want the WebSocket semantics, you can do that too.
294
+Simply leverage `send` and listen on the `message` event:
295
+
296
+#### Server side
297
+
298
+```js
299
+var io = require('socket.io').listen(80);
300
+
301
+io.sockets.on('connection', function (socket) {
302
+  socket.on('message', function () { });
303
+  socket.on('disconnect', function () { });
304
+});
305
+```
306
+
307
+#### Client side
308
+
309
+```html
310
+<script>
311
+  var socket = io.connect('http://localhost/');
312
+  socket.on('connect', function () {
313
+    socket.send('hi');
314
+
315
+    socket.on('message', function (msg) {
316
+      // my msg
317
+    });
318
+  });
319
+</script>
320
+```
321
+
322
+### Changing configuration
323
+
324
+Configuration in socket.io is TJ-style:
325
+
326
+#### Server side
327
+
328
+```js
329
+var io = require('socket.io').listen(80);
330
+
331
+io.configure(function () {
332
+  io.set('transports', ['websocket', 'flashsocket', 'xhr-polling']);
333
+});
334
+
335
+io.configure('development', function () {
336
+  io.set('transports', ['websocket', 'xhr-polling']);
337
+  io.enable('log');
338
+});
339
+```
340
+
341
+## License 
342
+
343
+(The MIT License)
344
+
345
+Copyright (c) 2011 Guillermo Rauch &lt;guillermo@learnboost.com&gt;
346
+
347
+Permission is hereby granted, free of charge, to any person obtaining
348
+a copy of this software and associated documentation files (the
349
+'Software'), to deal in the Software without restriction, including
350
+without limitation the rights to use, copy, modify, merge, publish,
351
+distribute, sublicense, and/or sell copies of the Software, and to
352
+permit persons to whom the Software is furnished to do so, subject to
353
+the following conditions:
354
+
355
+The above copyright notice and this permission notice shall be
356
+included in all copies or substantial portions of the Software.
357
+
358
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
359
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
360
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
361
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
362
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
363
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
364
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 64
- 0
node_modules/socket.io/benchmarks/decode.bench.js View File

@@ -0,0 +1,64 @@
1
+
2
+/**
3
+ * Module dependencies.
4
+ */
5
+
6
+var benchmark = require('benchmark')
7
+  , colors = require('colors')
8
+  , io = require('../')
9
+  , parser = io.parser
10
+  , suite = new benchmark.Suite('Decode packet');
11
+
12
+suite.add('string', function () {
13
+  parser.decodePacket('4:::"2"');
14
+});
15
+
16
+suite.add('event', function () {
17
+  parser.decodePacket('5:::{"name":"woot"}');
18
+});
19
+
20
+suite.add('event+ack', function () {
21
+  parser.decodePacket('5:1+::{"name":"tobi"}');
22
+});
23
+
24
+suite.add('event+data', function () {
25
+  parser.decodePacket('5:::{"name":"edwald","args":[{"a": "b"},2,"3"]}');
26
+});
27
+
28
+suite.add('heartbeat', function () {
29
+  parser.decodePacket('2:::');
30
+});
31
+
32
+suite.add('error', function () {
33
+  parser.decodePacket('7:::2+0');
34
+});
35
+
36
+var payload = parser.encodePayload([
37
+    parser.encodePacket({ type: 'message', data: '5', endpoint: '' })
38
+  , parser.encodePacket({ type: 'message', data: '53d', endpoint: '' })
39
+  , parser.encodePacket({ type: 'message', data: 'foobar', endpoint: '' })
40
+  , parser.encodePacket({ type: 'message', data: 'foobarbaz', endpoint: '' })
41
+  , parser.encodePacket({ type: 'message', data: 'foobarbazfoobarbaz', endpoint: '' })
42
+  , parser.encodePacket({ type: 'message', data: 'foobarbaz', endpoint: '' })
43
+  , parser.encodePacket({ type: 'message', data: 'foobar', endpoint: '' })
44
+]);
45
+
46
+suite.add('payload', function () {
47
+  parser.decodePayload(payload);
48
+});
49
+
50
+suite.on('cycle', function (bench, details) {
51
+  console.log('\n' + suite.name.grey, details.name.white.bold);
52
+  console.log([
53
+      details.hz.toFixed(2).cyan + ' ops/sec'.grey
54
+    , details.count.toString().white + ' times executed'.grey
55
+    , 'benchmark took '.grey + details.times.elapsed.toString().white + ' sec.'.grey
56
+    , 
57
+  ].join(', '.grey));
58
+});
59
+
60
+if (!module.parent) {
61
+  suite.run();
62
+} else {
63
+  module.exports = suite;
64
+}

+ 90
- 0
node_modules/socket.io/benchmarks/encode.bench.js View File

@@ -0,0 +1,90 @@
1
+
2
+/**
3
+ * Module dependencies.
4
+ */
5
+
6
+var benchmark = require('benchmark')
7
+  , colors = require('colors')
8
+  , io = require('../')
9
+  , parser = io.parser
10
+  , suite = new benchmark.Suite('Encode packet');
11
+
12
+suite.add('string', function () {
13
+  parser.encodePacket({
14
+      type: 'json'
15
+    , endpoint: ''
16
+    , data: '2'
17
+  });
18
+});
19
+
20
+suite.add('event', function () {
21
+  parser.encodePacket({
22
+      type: 'event'
23
+    , name: 'woot'
24
+    , endpoint: ''
25
+    , args: []
26
+  });
27
+});
28
+
29
+suite.add('event+ack', function () {
30
+  parser.encodePacket({
31
+      type: 'json'
32
+    , id: 1
33
+    , ack: 'data'
34
+    , endpoint: ''
35
+    , data: { a: 'b' }
36
+  });
37
+});
38
+
39
+suite.add('event+data', function () {
40
+  parser.encodePacket({
41
+      type: 'event'
42
+    , name: 'edwald'
43
+    , endpoint: ''
44
+    , args: [{a: 'b'}, 2, '3']
45
+  });
46
+});
47
+
48
+suite.add('heartbeat', function () {
49
+  parser.encodePacket({
50
+      type: 'heartbeat'
51
+    , endpoint: ''
52
+  })
53
+});
54
+
55
+suite.add('error', function () {
56
+  parser.encodePacket({
57
+      type: 'error'
58
+    , reason: 'unauthorized'
59
+    , advice: 'reconnect'
60
+    , endpoint: ''
61
+  })
62
+})
63
+
64
+suite.add('payload', function () {
65
+  parser.encodePayload([
66
+      parser.encodePacket({ type: 'message', data: '5', endpoint: '' })
67
+    , parser.encodePacket({ type: 'message', data: '53d', endpoint: '' })
68
+    , parser.encodePacket({ type: 'message', data: 'foobar', endpoint: '' })
69
+    , parser.encodePacket({ type: 'message', data: 'foobarbaz', endpoint: '' })
70
+    , parser.encodePacket({ type: 'message', data: 'foobarbazfoobarbaz', endpoint: '' })
71
+    , parser.encodePacket({ type: 'message', data: 'foobarbaz', endpoint: '' })
72
+    , parser.encodePacket({ type: 'message', data: 'foobar', endpoint: '' })
73
+  ]);
74
+});
75
+
76
+suite.on('cycle', function (bench, details) {
77
+  console.log('\n' + suite.name.grey, details.name.white.bold);
78
+  console.log([
79
+      details.hz.toFixed(2).cyan + ' ops/sec'.grey
80
+    , details.count.toString().white + ' times executed'.grey
81
+    , 'benchmark took '.grey + details.times.elapsed.toString().white + ' sec.'.grey
82
+    , 
83
+  ].join(', '.grey));
84
+});
85
+
86
+if (!module.parent) {
87
+  suite.run();
88
+} else {
89
+  module.exports = suite;
90
+}

+ 55
- 0
node_modules/socket.io/benchmarks/runner.js View File

@@ -0,0 +1,55 @@
1
+/**
2
+ * Benchmark runner dependencies
3
+ */
4
+
5
+var colors = require('colors')
6
+  , path = require('path');
7
+
8
+/**
9
+ * Find all the benchmarks
10
+ */
11
+
12
+var benchmarks_files = process.env.BENCHMARKS.split(' ')
13
+  , all = [].concat(benchmarks_files)
14
+  , first = all.shift()
15
+  , benchmarks = {};
16
+
17
+// find the benchmarks and load them all in our obj
18
+benchmarks_files.forEach(function (file) {
19
+  benchmarks[file] = require(path.join(__dirname, '..', file));
20
+});
21
+
22
+// setup the complete listeners
23
+benchmarks_files.forEach(function (file) {
24
+  var benchmark = benchmarks[file]
25
+    , next_file = all.shift()
26
+    , next = benchmarks[next_file];
27
+
28
+  /**
29
+   * Generate a oncomplete function for the tests, either we are done or we
30
+   * have more benchmarks to process.
31
+   */
32
+
33
+   function complete () {
34
+      if (!next) {
35
+        console.log(
36
+          '\n\nBenchmark completed in'.grey
37
+        , (Date.now() - start).toString().green + ' ms'.grey
38
+        );
39
+      } else {
40
+        console.log('\nStarting benchmark '.grey + next_file.yellow);
41
+        next.run();
42
+      }
43
+   }
44
+
45
+   // attach the listener
46
+   benchmark.on('complete', complete);
47
+});
48
+
49
+/**
50
+ * Start the benchmark
51
+ */
52
+
53
+var start = Date.now();
54
+console.log('Starting benchmark '.grey + first.yellow);
55
+benchmarks[first].run();

+ 8
- 0
node_modules/socket.io/index.js View File

@@ -0,0 +1,8 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+module.exports = require('./lib/socket.io');

+ 97
- 0
node_modules/socket.io/lib/logger.js View File

@@ -0,0 +1,97 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module dependencies.
10
+ */
11
+
12
+var util = require('./util')
13
+  , toArray = util.toArray;
14
+
15
+/**
16
+ * Log levels.
17
+ */
18
+
19
+var levels = [
20
+    'error'
21
+  , 'warn'
22
+  , 'info'
23
+  , 'debug'
24
+];
25
+
26
+/**
27
+ * Colors for log levels.
28
+ */
29
+
30
+var colors = [
31
+    31
32
+  , 33
33
+  , 36
34
+  , 90
35
+];
36
+
37
+/**
38
+ * Pads the nice output to the longest log level.
39
+ */
40
+
41
+function pad (str) {
42
+  var max = 0;
43
+
44
+  for (var i = 0, l = levels.length; i < l; i++)
45
+    max = Math.max(max, levels[i].length);
46
+
47
+  if (str.length < max)
48
+    return str + new Array(max - str.length + 1).join(' ');
49
+
50
+  return str;
51
+};
52
+
53
+/**
54
+ * Logger (console).
55
+ *
56
+ * @api public
57
+ */
58
+
59
+var Logger = module.exports = function (opts) {
60
+  opts = opts || {}
61
+  this.colors = false !== opts.colors;
62
+  this.level = 3;
63
+  this.enabled = true;
64
+};
65
+
66
+/**
67
+ * Log method.
68
+ *
69
+ * @api public
70
+ */
71
+
72
+Logger.prototype.log = function (type) {
73
+  var index = levels.indexOf(type);
74
+
75
+  if (index > this.level || !this.enabled)
76
+    return this;
77
+
78
+  console.log.apply(
79
+      console
80
+    , [this.colors
81
+        ? '   \033[' + colors[index] + 'm' + pad(type) + ' -\033[39m'
82
+        : type + ':'
83
+      ].concat(toArray(arguments).slice(1))
84
+  );
85
+
86
+  return this;
87
+};
88
+
89
+/**
90
+ * Generate methods.
91
+ */
92
+
93
+levels.forEach(function (name) {
94
+  Logger.prototype[name] = function () {
95
+    this.log.apply(this, [name].concat(toArray(arguments)));
96
+  };
97
+});

+ 1027
- 0
node_modules/socket.io/lib/manager.js
File diff suppressed because it is too large
View File


+ 355
- 0
node_modules/socket.io/lib/namespace.js View File

@@ -0,0 +1,355 @@
1
+/**
2
+ * Module dependencies.
3
+ */
4
+
5
+var Socket = require('./socket')
6
+  , EventEmitter = process.EventEmitter
7
+  , parser = require('./parser')
8
+  , util = require('./util');
9
+
10
+/**
11
+ * Exports the constructor.
12
+ */
13
+
14
+exports = module.exports = SocketNamespace;
15
+
16
+/**
17
+ * Constructor.
18
+ *
19
+ * @api public.
20
+ */
21
+
22
+function SocketNamespace (mgr, name) {
23
+  this.manager = mgr;
24
+  this.name = name || '';
25
+  this.sockets = {};
26
+  this.auth = false;
27
+  this.setFlags();
28
+};
29
+
30
+/**
31
+ * Inherits from EventEmitter.
32
+ */
33
+
34
+SocketNamespace.prototype.__proto__ = EventEmitter.prototype;
35
+
36
+/**
37
+ * Copies emit since we override it.
38
+ *
39
+ * @api private
40
+ */
41
+
42
+SocketNamespace.prototype.$emit = EventEmitter.prototype.emit;
43
+
44
+/**
45
+ * Retrieves all clients as Socket instances as an array.
46
+ *
47
+ * @api public
48
+ */
49
+
50
+SocketNamespace.prototype.clients = function (room) {
51
+  var room = this.name + (room !== undefined ?
52
+     '/' + room : '');
53
+
54
+  if (!this.manager.rooms[room]) {
55
+    return [];
56
+  }
57
+
58
+  return this.manager.rooms[room].map(function (id) {
59
+    return this.socket(id);
60
+  }, this);
61
+};
62
+
63
+/**
64
+ * Access logger interface.
65
+ *
66
+ * @api public
67
+ */
68
+
69
+SocketNamespace.prototype.__defineGetter__('log', function () {
70
+  return this.manager.log;
71
+});
72
+
73
+/**
74
+ * Access store.
75
+ *
76
+ * @api public
77
+ */
78
+
79
+SocketNamespace.prototype.__defineGetter__('store', function () {
80
+  return this.manager.store;
81
+});
82
+
83
+/**
84
+ * JSON message flag.
85
+ *
86
+ * @api public
87
+ */
88
+
89
+SocketNamespace.prototype.__defineGetter__('json', function () {
90
+  this.flags.json = true;
91
+  return this;
92
+});
93
+
94
+/**
95
+ * Volatile message flag.
96
+ *
97
+ * @api public
98
+ */
99
+
100
+SocketNamespace.prototype.__defineGetter__('volatile', function () {
101
+  this.flags.volatile = true;
102
+  return this;
103
+});
104
+
105
+/**
106
+ * Overrides the room to relay messages to (flag).
107
+ *
108
+ * @api public
109
+ */
110
+
111
+SocketNamespace.prototype.in = SocketNamespace.prototype.to = function (room) {
112
+  this.flags.endpoint = this.name + (room ? '/' + room : '');
113
+  return this;
114
+};
115
+
116
+/**
117
+ * Adds a session id we should prevent relaying messages to (flag).
118
+ *
119
+ * @api public
120
+ */
121
+
122
+SocketNamespace.prototype.except = function (id) {
123
+  this.flags.exceptions.push(id);
124
+  return this;
125
+};
126
+
127
+/**
128
+ * Sets the default flags.
129
+ *
130
+ * @api private
131
+ */
132
+
133
+SocketNamespace.prototype.setFlags = function () {
134
+  this.flags = {
135
+      endpoint: this.name
136
+    , exceptions: []
137
+  };
138
+  return this;
139
+};
140
+
141
+/**
142
+ * Sends out a packet.
143
+ *
144
+ * @api private
145
+ */
146
+
147
+SocketNamespace.prototype.packet = function (packet) {
148
+  packet.endpoint = this.name;
149
+
150
+  var store = this.store
151
+    , log = this.log
152
+    , volatile = this.flags.volatile
153
+    , exceptions = this.flags.exceptions
154
+    , packet = parser.encodePacket(packet);
155
+
156
+  this.manager.onDispatch(this.flags.endpoint, packet, volatile, exceptions);
157
+  this.store.publish('dispatch', this.flags.endpoint, packet, volatile, exceptions);
158
+
159
+  this.setFlags();
160
+
161
+  return this;
162
+};
163
+
164
+/**
165
+ * Sends to everyone.
166
+ *
167
+ * @api public
168
+ */
169
+
170
+SocketNamespace.prototype.send = function (data) {
171
+  return this.packet({
172
+      type: this.flags.json ? 'json' : 'message'
173
+    , data: data
174
+  });
175
+};
176
+
177
+/**
178
+ * Emits to everyone (override).
179
+ *
180
+ * @api public
181
+ */
182
+
183
+SocketNamespace.prototype.emit = function (name) {
184
+  if (name == 'newListener') {
185
+    return this.$emit.apply(this, arguments);
186
+  }
187
+
188
+  return this.packet({
189
+      type: 'event'
190
+    , name: name
191
+    , args: util.toArray(arguments).slice(1)
192
+  });
193
+};
194
+
195
+/**
196
+ * Retrieves or creates a write-only socket for a client, unless specified.
197
+ *
198
+ * @param {Boolean} whether the socket will be readable when initialized
199
+ * @api public
200
+ */
201
+
202
+SocketNamespace.prototype.socket = function (sid, readable) {
203
+  if (!this.sockets[sid]) {
204
+    this.sockets[sid] = new Socket(this.manager, sid, this, readable);
205
+  }
206
+
207
+  return this.sockets[sid];
208
+};
209
+
210
+/**
211
+ * Sets authorization for this namespace.
212
+ *
213
+ * @api public
214
+ */
215
+
216
+SocketNamespace.prototype.authorization = function (fn) {
217
+  this.auth = fn;
218
+  return this;
219
+};
220
+
221
+/**
222
+ * Called when a socket disconnects entirely.
223
+ *
224
+ * @api private
225
+ */
226
+
227
+SocketNamespace.prototype.handleDisconnect = function (sid, reason, raiseOnDisconnect) {
228
+  if (this.sockets[sid] && this.sockets[sid].readable) {
229
+    if (raiseOnDisconnect) this.sockets[sid].onDisconnect(reason);
230
+    delete this.sockets[sid];
231
+  }
232
+};
233
+
234
+/**
235
+ * Performs authentication.
236
+ *
237
+ * @param Object client request data
238
+ * @api private
239
+ */
240
+
241
+SocketNamespace.prototype.authorize = function (data, fn) {
242
+  if (this.auth) {
243
+    var self = this;
244
+
245
+    this.auth.call(this, data, function (err, authorized) {
246
+      self.log.debug('client ' +
247
+        (authorized ? '' : 'un') + 'authorized for ' + self.name);
248
+      fn(err, authorized);
249
+    });
250
+  } else {
251
+    this.log.debug('client authorized for ' + this.name);
252
+    fn(null, true);
253
+  }
254
+
255
+  return this;
256
+};
257
+
258
+/**
259
+ * Handles a packet.
260
+ *
261
+ * @api private
262
+ */
263
+
264
+SocketNamespace.prototype.handlePacket = function (sessid, packet) {
265
+  var socket = this.socket(sessid)
266
+    , dataAck = packet.ack == 'data'
267
+    , manager = this.manager
268
+    , self = this;
269
+
270
+  function ack () {
271
+    self.log.debug('sending data ack packet');
272
+    socket.packet({
273
+        type: 'ack'
274
+      , args: util.toArray(arguments)
275
+      , ackId: packet.id
276
+    });
277
+  };
278
+
279
+  function error (err) {
280
+    self.log.warn('handshake error ' + err + ' for ' + self.name);
281
+    socket.packet({ type: 'error', reason: err });
282
+  };
283
+
284
+  function connect () {
285
+    self.manager.onJoin(sessid, self.name);
286
+    self.store.publish('join', sessid, self.name);
287
+
288
+    // packet echo
289
+    socket.packet({ type: 'connect' });
290
+
291
+    // emit connection event
292
+    self.$emit('connection', socket);
293
+  };
294
+
295
+  switch (packet.type) {
296
+    case 'connect':
297
+      if (packet.endpoint == '') {
298
+        connect();
299
+      } else {
300
+        var handshakeData = manager.handshaken[sessid];
301
+
302
+        this.authorize(handshakeData, function (err, authorized, newData) {
303
+          if (err) return error(err);
304
+
305
+          if (authorized) {
306
+            manager.onHandshake(sessid, newData || handshakeData);
307
+            self.store.publish('handshake', sessid, newData || handshakeData);
308
+            connect();
309
+          } else {
310
+            error('unauthorized');
311
+          }
312
+        });
313
+      }
314
+      break;
315
+
316
+    case 'ack':
317
+      if (socket.acks[packet.ackId]) {
318
+        socket.acks[packet.ackId].apply(socket, packet.args);
319
+      } else {
320
+        this.log.info('unknown ack packet');
321
+      }
322
+      break;
323
+
324
+    case 'event':
325
+      // check if the emitted event is not blacklisted
326
+      if (-~manager.get('blacklist').indexOf(packet.name)) {
327
+        this.log.debug('ignoring blacklisted event `' + packet.name + '`');
328
+      } else {
329
+        var params = [packet.name].concat(packet.args);
330
+
331
+        if (dataAck) {
332
+          params.push(ack);
333
+        }
334
+
335
+        socket.$emit.apply(socket, params);
336
+      }
337
+      break;
338
+
339
+    case 'disconnect':
340
+      this.manager.onLeave(sessid, this.name);
341
+      this.store.publish('leave', sessid, this.name);
342
+
343
+      socket.$emit('disconnect', packet.reason || 'packet');
344
+      break;
345
+
346
+    case 'json':
347
+    case 'message':
348
+      var params = ['message', packet.data];
349
+
350
+      if (dataAck)
351
+        params.push(ack);
352
+
353
+      socket.$emit.apply(socket, params);
354
+  };
355
+};

+ 249
- 0
node_modules/socket.io/lib/parser.js View File

@@ -0,0 +1,249 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module dependencies.
10
+ */
11
+
12
+/**
13
+ * Packet types.
14
+ */
15
+
16
+var packets = exports.packets = {
17
+      'disconnect': 0
18
+    , 'connect': 1
19
+    , 'heartbeat': 2
20
+    , 'message': 3
21
+    , 'json': 4
22
+    , 'event': 5
23
+    , 'ack': 6
24
+    , 'error': 7
25
+    , 'noop': 8
26
+  }
27
+  , packetslist = Object.keys(packets);
28
+
29
+/**
30
+ * Errors reasons.
31
+ */
32
+
33
+var reasons = exports.reasons = {
34
+      'transport not supported': 0
35
+    , 'client not handshaken': 1
36
+    , 'unauthorized': 2
37
+  }
38
+  , reasonslist = Object.keys(reasons);
39
+
40
+/**
41
+ * Errors advice.
42
+ */
43
+
44
+var advice = exports.advice = {
45
+      'reconnect': 0
46
+  }
47
+  , advicelist = Object.keys(advice);
48
+
49
+/**
50
+ * Encodes a packet.
51
+ *
52
+ * @api private
53
+ */
54
+
55
+exports.encodePacket = function (packet) {
56
+  var type = packets[packet.type]
57
+    , id = packet.id || ''
58
+    , endpoint = packet.endpoint || ''
59
+    , ack = packet.ack
60
+    , data = null;
61
+
62
+  switch (packet.type) {
63
+    case 'message':
64
+      if (packet.data !== '')
65
+        data = packet.data;
66
+      break;
67
+
68
+    case 'event':
69
+      var ev = { name: packet.name };
70
+
71
+      if (packet.args && packet.args.length) {
72
+        ev.args = packet.args;
73
+      }
74
+
75
+      data = JSON.stringify(ev);
76
+      break;
77
+
78
+    case 'json':
79
+      data = JSON.stringify(packet.data);
80
+      break;
81
+
82
+    case 'ack':
83
+      data = packet.ackId
84
+        + (packet.args && packet.args.length
85
+            ? '+' + JSON.stringify(packet.args) : '');
86
+      break;
87
+
88
+    case 'connect':
89
+      if (packet.qs)
90
+        data = packet.qs;
91
+      break;
92
+
93
+     case 'error':
94
+      var reason = packet.reason ? reasons[packet.reason] : ''
95
+        , adv = packet.advice ? advice[packet.advice] : ''
96
+
97
+      if (reason !== '' || adv !== '')
98
+        data = reason + (adv !== '' ? ('+' + adv) : '')
99
+
100
+      break;
101
+  }
102
+
103
+  // construct packet with required fragments
104
+  var encoded = type + ':' + id + (ack == 'data' ? '+' : '') + ':' + endpoint;
105
+
106
+  // data fragment is optional
107
+  if (data !== null && data !== undefined)
108
+    encoded += ':' + data;
109
+
110
+  return encoded;
111
+};
112
+
113
+/**
114
+ * Encodes multiple messages (payload).
115
+ *
116
+ * @param {Array} messages
117
+ * @api private
118
+ */
119
+
120
+exports.encodePayload = function (packets) {
121
+  var decoded = '';
122
+
123
+  if (packets.length == 1)
124
+    return packets[0];
125
+
126
+  for (var i = 0, l = packets.length; i < l; i++) {
127
+    var packet = packets[i];
128
+    decoded += '\ufffd' + packet.length + '\ufffd' + packets[i]
129
+  }
130
+
131
+  return decoded;
132
+};
133
+
134
+/**
135
+ * Decodes a packet
136
+ *
137
+ * @api private
138
+ */
139
+
140
+var regexp = /([^:]+):([0-9]+)?(\+)?:([^:]+)?:?([\s\S]*)?/;
141
+
142
+/**
143
+ * Wrap the JSON.parse in a seperate function the crankshaft optimizer will
144
+ * only punish this function for the usage for try catch
145
+ *
146
+ * @api private
147
+ */
148
+
149
+function parse (data) {
150
+  try { return JSON.parse(data) }
151
+  catch (e) { return false }
152
+}
153
+
154
+exports.decodePacket = function (data) {
155
+  var pieces = data.match(regexp);
156
+
157
+  if (!pieces) return {};
158
+
159
+  var id = pieces[2] || ''
160
+    , data = pieces[5] || ''
161
+    , packet = {
162
+          type: packetslist[pieces[1]]
163
+        , endpoint: pieces[4] || ''
164
+      };
165
+
166
+  // whether we need to acknowledge the packet
167
+  if (id) {
168
+    packet.id = id;
169
+    if (pieces[3])
170
+      packet.ack = 'data';
171
+    else
172
+      packet.ack = true;
173
+  }
174
+
175
+  // handle different packet types
176
+  switch (packet.type) {
177
+    case 'message':
178
+      packet.data = data || '';
179
+      break;
180
+
181
+    case 'event':
182
+      pieces = parse(data);
183
+      if (pieces) {
184
+        packet.name = pieces.name;
185
+        packet.args = pieces.args;
186
+      }
187
+
188
+      packet.args = packet.args || [];
189
+      break;
190
+
191
+    case 'json':
192
+      packet.data = parse(data);
193
+      break;
194
+
195
+    case 'connect':
196
+      packet.qs = data || '';
197
+      break;
198
+
199
+    case 'ack':
200
+      pieces = data.match(/^([0-9]+)(\+)?(.*)/);
201
+      if (pieces) {
202
+        packet.ackId = pieces[1];
203
+        packet.args = [];
204
+
205
+        if (pieces[3]) {
206
+          packet.args = parse(pieces[3]) || [];
207
+        }
208
+      }
209
+      break;
210
+
211
+    case 'error':
212
+      pieces = data.split('+');
213
+      packet.reason = reasonslist[pieces[0]] || '';
214
+      packet.advice = advicelist[pieces[1]] || '';
215
+  }
216
+
217
+  return packet;
218
+};
219
+
220
+/**
221
+ * Decodes data payload. Detects multiple messages
222
+ *
223
+ * @return {Array} messages
224
+ * @api public
225
+ */
226
+
227
+exports.decodePayload = function (data) {
228
+  if (undefined == data || null == data) {
229
+    return [];
230
+  }
231
+
232
+  if (data[0] == '\ufffd') {
233
+    var ret = [];
234
+
235
+    for (var i = 1, length = ''; i < data.length; i++) {
236
+      if (data[i] == '\ufffd') {
237
+        ret.push(exports.decodePacket(data.substr(i + 1, length)));
238
+        i += Number(length) + 1;
239
+        length = '';
240
+      } else {
241
+        length += data[i];
242
+      }
243
+    }
244
+
245
+    return ret;
246
+  } else {
247
+    return [exports.decodePacket(data)];
248
+  }
249
+};

+ 143
- 0
node_modules/socket.io/lib/socket.io.js View File

@@ -0,0 +1,143 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module dependencies.
10
+ */
11
+
12
+var client = require('socket.io-client');
13
+
14
+/**
15
+ * Version.
16
+ */
17
+
18
+exports.version = '0.9.16';
19
+
20
+/**
21
+ * Supported protocol version.
22
+ */
23
+
24
+exports.protocol = 1;
25
+
26
+/**
27
+ * Client that we serve.
28
+ */
29
+
30
+exports.clientVersion = client.version;
31
+
32
+/**
33
+ * Attaches a manager
34
+ *
35
+ * @param {HTTPServer/Number} a HTTP/S server or a port number to listen on.
36
+ * @param {Object} opts to be passed to Manager and/or http server
37
+ * @param {Function} callback if a port is supplied
38
+ * @api public
39
+ */
40
+
41
+exports.listen = function (server, options, fn) {
42
+  if ('function' == typeof server) {
43
+    console.warn('Socket.IO\'s `listen()` method expects an `http.Server` instance\n'
44
+    + 'as its first parameter. Are you migrating from Express 2.x to 3.x?\n'
45
+    + 'If so, check out the "Socket.IO compatibility" section at:\n'
46
+    + 'https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x');
47
+  }
48
+
49
+  if ('function' == typeof options) {
50
+    fn = options;
51
+    options = {};
52
+  }
53
+
54
+  if ('undefined' == typeof server) {
55
+    // create a server that listens on port 80
56
+    server = 80;
57
+  }
58
+
59
+  if ('number' == typeof server) {
60
+    // if a port number is passed
61
+    var port = server;
62
+
63
+    if (options && options.key)
64
+      server = require('https').createServer(options);
65
+    else
66
+      server = require('http').createServer();
67
+
68
+    // default response
69
+    server.on('request', function (req, res) {
70
+      res.writeHead(200);
71
+      res.end('Welcome to socket.io.');
72
+    });
73
+
74
+    server.listen(port, fn);
75
+  }
76
+
77
+  // otherwise assume a http/s server
78
+  return new exports.Manager(server, options);
79
+};
80
+
81
+/**
82
+ * Manager constructor.
83
+ *
84
+ * @api public
85
+ */
86
+
87
+exports.Manager = require('./manager');
88
+
89
+/**
90
+ * Transport constructor.
91
+ *
92
+ * @api public
93
+ */
94
+
95
+exports.Transport = require('./transport');
96
+
97
+/**
98
+ * Socket constructor.
99
+ *
100
+ * @api public
101
+ */
102
+
103
+exports.Socket = require('./socket');
104
+
105
+/**
106
+ * Static constructor.
107
+ *
108
+ * @api public
109
+ */
110
+
111
+exports.Static = require('./static');
112
+
113
+/**
114
+ * Store constructor.
115
+ *
116
+ * @api public
117
+ */
118
+
119
+exports.Store = require('./store');
120
+
121
+/**
122
+ * Memory Store constructor.
123
+ *
124
+ * @api public
125
+ */
126
+
127
+exports.MemoryStore = require('./stores/memory');
128
+
129
+/**
130
+ * Redis Store constructor.
131
+ *
132
+ * @api public
133
+ */
134
+
135
+exports.RedisStore = require('./stores/redis');
136
+
137
+/**
138
+ * Parser.
139
+ *
140
+ * @api public
141
+ */
142
+
143
+exports.parser = require('./parser');

+ 369
- 0
node_modules/socket.io/lib/socket.js View File

@@ -0,0 +1,369 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module dependencies.
10
+ */
11
+
12
+var parser = require('./parser')
13
+  , util = require('./util')
14
+  , EventEmitter = process.EventEmitter
15
+
16
+/**
17
+ * Export the constructor.
18
+ */
19
+
20
+exports = module.exports = Socket;
21
+
22
+/**
23
+ * Default error event listener to prevent uncaught exceptions.
24
+ */
25
+
26
+var defaultError = function () {};
27
+
28
+/**
29
+ * Socket constructor.
30
+ *
31
+ * @param {Manager} manager instance
32
+ * @param {String} session id
33
+ * @param {Namespace} namespace the socket belongs to
34
+ * @param {Boolean} whether the 
35
+ * @api public
36
+ */
37
+
38
+function Socket (manager, id, nsp, readable) {
39
+  this.id = id;
40
+  this.namespace = nsp;
41
+  this.manager = manager;
42
+  this.disconnected = false;
43
+  this.ackPackets = 0;
44
+  this.acks = {};
45
+  this.setFlags();
46
+  this.readable = readable;
47
+  this.store = this.manager.store.client(this.id);
48
+  this.on('error', defaultError);
49
+};
50
+
51
+/**
52
+ * Inherits from EventEmitter.
53
+ */
54
+
55
+Socket.prototype.__proto__ = EventEmitter.prototype;
56
+
57
+/**
58
+ * Accessor shortcut for the handshake data
59
+ *
60
+ * @api private
61
+ */
62
+
63
+Socket.prototype.__defineGetter__('handshake', function () {
64
+  return this.manager.handshaken[this.id];
65
+});
66
+
67
+/**
68
+ * Accessor shortcut for the transport type
69
+ *
70
+ * @api private
71
+ */
72
+
73
+Socket.prototype.__defineGetter__('transport', function () {
74
+  return this.manager.transports[this.id].name;
75
+});
76
+
77
+/**
78
+ * Accessor shortcut for the logger.
79
+ *
80
+ * @api private
81
+ */
82
+
83
+Socket.prototype.__defineGetter__('log', function () {
84
+  return this.manager.log;
85
+});
86
+
87
+/**
88
+ * JSON message flag.
89
+ *
90
+ * @api public
91
+ */
92
+
93
+Socket.prototype.__defineGetter__('json', function () {
94
+  this.flags.json = true;
95
+  return this;
96
+});
97
+
98
+/**
99
+ * Volatile message flag.
100
+ *
101
+ * @api public
102
+ */
103
+
104
+Socket.prototype.__defineGetter__('volatile', function () {
105
+  this.flags.volatile = true;
106
+  return this;
107
+});
108
+
109
+/**
110
+ * Broadcast message flag.
111
+ *
112
+ * @api public
113
+ */
114
+
115
+Socket.prototype.__defineGetter__('broadcast', function () {
116
+  this.flags.broadcast = true;
117
+  return this;
118
+});
119
+
120
+/**
121
+ * Overrides the room to broadcast messages to (flag)
122
+ *
123
+ * @api public
124
+ */
125
+
126
+Socket.prototype.to = Socket.prototype.in = function (room) {
127
+  this.flags.room = room;
128
+  return this;
129
+};
130
+
131
+/**
132
+ * Resets flags
133
+ *
134
+ * @api private
135
+ */
136
+
137
+Socket.prototype.setFlags = function () {
138
+  this.flags = {
139
+      endpoint: this.namespace.name
140
+    , room: ''
141
+  };
142
+  return this;
143
+};
144
+
145
+/**
146
+ * Triggered on disconnect
147
+ *
148
+ * @api private
149
+ */
150
+
151
+Socket.prototype.onDisconnect = function (reason) {
152
+  if (!this.disconnected) {
153
+    this.$emit('disconnect', reason);
154
+    this.disconnected = true;
155
+  }
156
+};
157
+
158
+/**
159
+ * Joins a user to a room.
160
+ *
161
+ * @api public
162
+ */
163
+
164
+Socket.prototype.join = function (name, fn) {
165
+  var nsp = this.namespace.name
166
+    , name = (nsp + '/') + name;
167
+
168
+  this.manager.onJoin(this.id, name);
169
+  this.manager.store.publish('join', this.id, name);
170
+
171
+  if (fn) {
172
+    this.log.warn('Client#join callback is deprecated');
173
+    fn();
174
+  }
175
+
176
+  return this;
177
+};
178
+
179
+/**
180
+ * Un-joins a user from a room.
181
+ *
182
+ * @api public
183
+ */
184
+
185
+Socket.prototype.leave = function (name, fn) {
186
+  var nsp = this.namespace.name
187
+    , name = (nsp + '/') + name;
188
+
189
+  this.manager.onLeave(this.id, name);
190
+  this.manager.store.publish('leave', this.id, name);
191
+
192
+  if (fn) {
193
+    this.log.warn('Client#leave callback is deprecated');
194
+    fn();
195
+  }
196
+
197
+  return this;
198
+};
199
+
200
+/**
201
+ * Transmits a packet.
202
+ *
203
+ * @api private
204
+ */
205
+
206
+Socket.prototype.packet = function (packet) {
207
+  if (this.flags.broadcast) {
208
+    this.log.debug('broadcasting packet');
209
+    this.namespace.in(this.flags.room).except(this.id).packet(packet);
210
+  } else {
211
+    packet.endpoint = this.flags.endpoint;
212
+    packet = parser.encodePacket(packet);
213
+
214
+    this.dispatch(packet, this.flags.volatile);
215
+  }
216
+
217
+  this.setFlags();
218
+
219
+  return this;
220
+};
221
+
222
+/**
223
+ * Dispatches a packet
224
+ *
225
+ * @api private
226
+ */
227
+
228
+Socket.prototype.dispatch = function (packet, volatile) {
229
+  if (this.manager.transports[this.id] && this.manager.transports[this.id].open) {
230
+    this.manager.transports[this.id].onDispatch(packet, volatile);
231
+  } else {
232
+    if (!volatile) {
233
+      this.manager.onClientDispatch(this.id, packet, volatile);
234
+    }
235
+
236
+    this.manager.store.publish('dispatch:' + this.id, packet, volatile);
237
+  }
238
+};
239
+
240
+/**
241
+ * Stores data for the client.
242
+ *
243
+ * @api public
244
+ */
245
+
246
+Socket.prototype.set = function (key, value, fn) {
247
+  this.store.set(key, value, fn);
248
+  return this;
249
+};
250
+
251
+/**
252
+ * Retrieves data for the client
253
+ *
254
+ * @api public
255
+ */
256
+
257
+Socket.prototype.get = function (key, fn) {
258
+  this.store.get(key, fn);
259
+  return this;
260
+};
261
+
262
+/**
263
+ * Checks data for the client
264
+ *
265
+ * @api public
266
+ */
267
+
268
+Socket.prototype.has = function (key, fn) {
269
+  this.store.has(key, fn);
270
+  return this;
271
+};
272
+
273
+/**
274
+ * Deletes data for the client
275
+ *
276
+ * @api public
277
+ */
278
+
279
+Socket.prototype.del = function (key, fn) {
280
+  this.store.del(key, fn);
281
+  return this;
282
+};
283
+
284
+/**
285
+ * Kicks client
286
+ *
287
+ * @api public
288
+ */
289
+
290
+Socket.prototype.disconnect = function () {
291
+  if (!this.disconnected) {
292
+    this.log.info('booting client');
293
+
294
+    if ('' === this.namespace.name) {
295
+      if (this.manager.transports[this.id] && this.manager.transports[this.id].open) {
296
+        this.manager.transports[this.id].onForcedDisconnect();
297
+      } else {
298
+        this.manager.onClientDisconnect(this.id);
299
+        this.manager.store.publish('disconnect:' + this.id);
300
+      }
301
+    } else {
302
+      this.packet({type: 'disconnect'});
303
+      this.manager.onLeave(this.id, this.namespace.name);
304
+      this.$emit('disconnect', 'booted');
305
+    }
306
+
307
+  }
308
+
309
+  return this;
310
+};
311
+
312
+/**
313
+ * Send a message.
314
+ *
315
+ * @api public
316
+ */
317
+
318
+Socket.prototype.send = function (data, fn) {
319
+  var packet = {
320
+      type: this.flags.json ? 'json' : 'message'
321
+    , data: data
322
+  };
323
+
324
+  if (fn) {
325
+    packet.id = ++this.ackPackets;
326
+    packet.ack = true;
327
+    this.acks[packet.id] = fn;
328
+  }
329
+
330
+  return this.packet(packet);
331
+};
332
+
333
+/**
334
+ * Original emit function.
335
+ *
336
+ * @api private
337
+ */
338
+
339
+Socket.prototype.$emit = EventEmitter.prototype.emit;
340
+
341
+/**
342
+ * Emit override for custom events.
343
+ *
344
+ * @api public
345
+ */
346
+
347
+Socket.prototype.emit = function (ev) {
348
+  if (ev == 'newListener') {
349
+    return this.$emit.apply(this, arguments);
350
+  }
351
+
352
+  var args = util.toArray(arguments).slice(1)
353
+    , lastArg = args[args.length - 1]
354
+    , packet = {
355
+          type: 'event'
356
+        , name: ev
357
+      };
358
+
359
+  if ('function' == typeof lastArg) {
360
+    packet.id = ++this.ackPackets;
361
+    packet.ack = lastArg.length ? 'data' : true;
362
+    this.acks[packet.id] = lastArg;
363
+    args = args.slice(0, args.length - 1);
364
+  }
365
+
366
+  packet.args = args;
367
+
368
+  return this.packet(packet);
369
+};

+ 395
- 0
node_modules/socket.io/lib/static.js View File

@@ -0,0 +1,395 @@
1
+
2
+/*!
3
+* socket.io-node
4
+* Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+* MIT Licensed
6
+*/
7
+
8
+/**
9
+ * Module dependencies.
10
+ */
11
+
12
+var client = require('socket.io-client')
13
+  , cp = require('child_process')
14
+  , fs = require('fs')
15
+  , util = require('./util');
16
+
17
+/**
18
+ * File type details.
19
+ *
20
+ * @api private
21
+ */
22
+
23
+var mime = {
24
+    js: {
25
+        type: 'application/javascript'
26
+      , encoding: 'utf8'
27
+      , gzip: true
28
+    }
29
+  , swf: {
30
+        type: 'application/x-shockwave-flash'
31
+      , encoding: 'binary'
32
+      , gzip: false
33
+    }
34
+};
35
+
36
+/**
37
+ * Regexp for matching custom transport patterns. Users can configure their own
38
+ * socket.io bundle based on the url structure. Different transport names are
39
+ * concatinated using the `+` char. /socket.io/socket.io+websocket.js should
40
+ * create a bundle that only contains support for the websocket.
41
+ *
42
+ * @api private
43
+ */
44
+
45
+var bundle = /\+((?:\+)?[\w\-]+)*(?:\.v\d+\.\d+\.\d+)?(?:\.js)$/
46
+  , versioning = /\.v\d+\.\d+\.\d+(?:\.js)$/;
47
+
48
+/**
49
+ * Export the constructor
50
+ */
51
+
52
+exports = module.exports = Static;
53
+
54
+/**
55
+ * Static constructor
56
+ *
57
+ * @api public
58
+ */
59
+
60
+function Static (manager) {
61
+  this.manager = manager;
62
+  this.cache = {};
63
+  this.paths = {};
64
+
65
+  this.init();
66
+}
67
+
68
+/**
69
+ * Initialize the Static by adding default file paths.
70
+ *
71
+ * @api public
72
+ */
73
+
74
+Static.prototype.init = function () {
75
+  /**
76
+   * Generates a unique id based the supplied transports array
77
+   *
78
+   * @param {Array} transports The array with transport types
79
+   * @api private
80
+   */
81
+  function id (transports) {
82
+    var id = transports.join('').split('').map(function (char) {
83
+      return ('' + char.charCodeAt(0)).split('').pop();
84
+    }).reduce(function (char, id) {
85
+      return char +id;
86
+    });
87
+
88
+    return client.version + ':' + id;
89
+  }
90
+
91
+  /**
92
+   * Generates a socket.io-client file based on the supplied transports.
93
+   *
94
+   * @param {Array} transports The array with transport types
95
+   * @param {Function} callback Callback for the static.write
96
+   * @api private
97
+   */
98
+
99
+  function build (transports, callback) {
100
+    client.builder(transports, {
101
+          minify: self.manager.enabled('browser client minification')
102
+      }, function (err, content) {
103
+        callback(err, content ? new Buffer(content) : null, id(transports));
104
+      }
105
+    );
106
+  }
107
+
108
+  var self = this;
109
+
110
+  // add our default static files
111
+  this.add('/static/flashsocket/WebSocketMain.swf', {
112
+      file: client.dist + '/WebSocketMain.swf'
113
+  });
114
+
115
+  this.add('/static/flashsocket/WebSocketMainInsecure.swf', {
116
+      file: client.dist + '/WebSocketMainInsecure.swf'
117
+  });
118
+
119
+  // generates dedicated build based on the available transports
120
+  this.add('/socket.io.js', function (path, callback) {
121
+    build(self.manager.get('transports'), callback);
122
+  });
123
+
124
+  this.add('/socket.io.v', { mime: mime.js }, function (path, callback) {
125
+    build(self.manager.get('transports'), callback);
126
+  });
127
+
128
+  // allow custom builds based on url paths
129
+  this.add('/socket.io+', { mime: mime.js }, function (path, callback) {
130
+    var available = self.manager.get('transports')
131
+      , matches = path.match(bundle)
132
+      , transports = [];
133
+
134
+    if (!matches) return callback('No valid transports');
135
+
136
+    // make sure they valid transports
137
+    matches[0].split('.')[0].split('+').slice(1).forEach(function (transport) {
138
+      if (!!~available.indexOf(transport)) {
139
+        transports.push(transport);
140
+      }
141
+    });
142
+
143
+    if (!transports.length) return callback('No valid transports');
144
+    build(transports, callback);
145
+  });
146
+
147
+  // clear cache when transports change
148
+  this.manager.on('set:transports', function (key, value) {
149
+    delete self.cache['/socket.io.js'];
150
+    Object.keys(self.cache).forEach(function (key) {
151
+      if (bundle.test(key)) {
152
+        delete self.cache[key];
153
+      }
154
+    });
155
+  });
156
+};
157
+
158
+/**
159
+ * Gzip compress buffers.
160
+ *
161
+ * @param {Buffer} data The buffer that needs gzip compression
162
+ * @param {Function} callback
163
+ * @api public
164
+ */
165
+
166
+Static.prototype.gzip = function (data, callback) {
167
+  var gzip = cp.spawn('gzip', ['-9', '-c', '-f', '-n'])
168
+    , encoding = Buffer.isBuffer(data) ? 'binary' : 'utf8'
169
+    , buffer = []
170
+    , err;
171
+
172
+  gzip.stdout.on('data', function (data) {
173
+    buffer.push(data);
174
+  });
175
+
176
+  gzip.stderr.on('data', function (data) {
177
+    err = data +'';
178
+    buffer.length = 0;
179
+  });
180
+
181
+  gzip.on('close', function () {
182
+    if (err) return callback(err);
183
+
184
+    var size = 0
185
+      , index = 0
186
+      , i = buffer.length
187
+      , content;
188
+
189
+    while (i--) {
190
+      size += buffer[i].length;
191
+    }
192
+
193
+    content = new Buffer(size);
194
+    i = buffer.length;
195
+
196
+    buffer.forEach(function (buffer) {
197
+      var length = buffer.length;
198
+
199
+      buffer.copy(content, index, 0, length);
200
+      index += length;
201
+    });
202
+
203
+    buffer.length = 0;
204
+    callback(null, content);
205
+  });
206
+
207
+  gzip.stdin.end(data, encoding);
208
+};
209
+
210
+/**
211
+ * Is the path a static file?
212
+ *
213
+ * @param {String} path The path that needs to be checked
214
+ * @api public
215
+ */
216
+
217
+Static.prototype.has = function (path) {
218
+  // fast case
219
+  if (this.paths[path]) return this.paths[path];
220
+
221
+  var keys = Object.keys(this.paths)
222
+    , i = keys.length;
223
+ 
224
+  while (i--) {
225
+    if (-~path.indexOf(keys[i])) return this.paths[keys[i]];
226
+  }
227
+
228
+  return false;
229
+};
230
+
231
+/**
232
+ * Add new paths new paths that can be served using the static provider.
233
+ *
234
+ * @param {String} path The path to respond to
235
+ * @param {Options} options Options for writing out the response
236
+ * @param {Function} [callback] Optional callback if no options.file is
237
+ * supplied this would be called instead.
238
+ * @api public
239
+ */
240
+
241
+Static.prototype.add = function (path, options, callback) {
242
+  var extension = /(?:\.(\w{1,4}))$/.exec(path);
243
+
244
+  if (!callback && typeof options == 'function') {
245
+    callback = options;
246
+    options = {};
247
+  }
248
+
249
+  options.mime = options.mime || (extension ? mime[extension[1]] : false);
250
+
251
+  if (callback) options.callback = callback;
252
+  if (!(options.file || options.callback) || !options.mime) return false;
253
+
254
+  this.paths[path] = options;
255
+
256
+  return true;
257
+};
258
+
259
+/**
260
+ * Writes a static response.
261
+ *
262
+ * @param {String} path The path for the static content
263
+ * @param {HTTPRequest} req The request object
264
+ * @param {HTTPResponse} res The response object
265
+ * @api public
266
+ */
267
+
268
+Static.prototype.write = function (path, req, res) {
269
+  /**
270
+   * Write a response without throwing errors because can throw error if the
271
+   * response is no longer writable etc.
272
+   *
273
+   * @api private
274
+   */
275
+
276
+  function write (status, headers, content, encoding) {
277
+    try {
278
+      res.writeHead(status, headers || undefined);
279
+
280
+      // only write content if it's not a HEAD request and we actually have
281
+      // some content to write (304's doesn't have content).
282
+      res.end(
283
+          req.method !== 'HEAD' && content ? content : ''
284
+        , encoding || undefined
285
+      );
286
+    } catch (e) {}
287
+  }
288
+
289
+  /**
290
+   * Answers requests depending on the request properties and the reply object.
291
+   *
292
+   * @param {Object} reply The details and content to reply the response with
293
+   * @api private
294
+   */
295
+
296
+  function answer (reply) {
297
+    var cached = req.headers['if-none-match'] === reply.etag;
298
+    if (cached && self.manager.enabled('browser client etag')) {
299
+      return write(304);
300
+    }
301
+
302
+    var accept = req.headers['accept-encoding'] || ''
303
+      , gzip = !!~accept.toLowerCase().indexOf('gzip')
304
+      , mime = reply.mime
305
+      , versioned = reply.versioned
306
+      , headers = {
307
+          'Content-Type': mime.type
308
+      };
309
+
310
+    // check if we can add a etag
311
+    if (self.manager.enabled('browser client etag') && reply.etag && !versioned) {
312
+      headers['Etag'] = reply.etag;
313
+    }
314
+
315
+    // see if we need to set Expire headers because the path is versioned
316
+    if (versioned) {
317
+      var expires = self.manager.get('browser client expires');
318
+      headers['Cache-Control'] = 'private, x-gzip-ok="", max-age=' + expires;
319
+      headers['Date'] = new Date().toUTCString();
320
+      headers['Expires'] = new Date(Date.now() + (expires * 1000)).toUTCString();
321
+    }
322
+
323
+    if (gzip && reply.gzip) {
324
+      headers['Content-Length'] = reply.gzip.length;
325
+      headers['Content-Encoding'] = 'gzip';
326
+      headers['Vary'] = 'Accept-Encoding';
327
+      write(200, headers, reply.gzip.content, mime.encoding);
328
+    } else {
329
+      headers['Content-Length'] = reply.length;
330
+      write(200, headers, reply.content, mime.encoding);
331
+    }
332
+
333
+    self.manager.log.debug('served static content ' + path);
334
+  }
335
+
336
+  var self = this
337
+    , details;
338
+
339
+  // most common case first
340
+  if (this.manager.enabled('browser client cache') && this.cache[path]) {
341
+    return answer(this.cache[path]);
342
+  } else if (this.manager.get('browser client handler')) {
343
+    return this.manager.get('browser client handler').call(this, req, res);
344
+  } else if ((details = this.has(path))) {
345
+    /**
346
+     * A small helper function that will let us deal with fs and dynamic files
347
+     *
348
+     * @param {Object} err Optional error
349
+     * @param {Buffer} content The data
350
+     * @api private
351
+     */
352
+
353
+    function ready (err, content, etag) {
354
+      if (err) {
355
+        self.manager.log.warn('Unable to serve file. ' + (err.message || err));
356
+        return write(500, null, 'Error serving static ' + path);
357
+      }
358
+
359
+      // store the result in the cache
360
+      var reply = self.cache[path] = {
361
+            content: content
362
+          , length: content.length
363
+          , mime: details.mime
364
+          , etag: etag || client.version
365
+          , versioned: versioning.test(path)
366
+        };
367
+
368
+      // check if gzip is enabled
369
+      if (details.mime.gzip && self.manager.enabled('browser client gzip')) {
370
+        self.gzip(content, function (err, content) {
371
+          if (!err) {
372
+            reply.gzip = {
373
+                content: content
374
+              , length: content.length
375
+            }
376
+          }
377
+
378
+          answer(reply);
379
+        });
380
+      } else {
381
+        answer(reply);
382
+      }
383
+    }
384
+
385
+    if (details.file) {
386
+      fs.readFile(details.file, ready);
387
+    } else if(details.callback) {
388
+      details.callback.call(this, path, ready);
389
+    } else {
390
+      write(404, null, 'File handle not found');
391
+    }
392
+  } else {
393
+    write(404, null, 'File not found');
394
+  }
395
+};

+ 98
- 0
node_modules/socket.io/lib/store.js View File

@@ -0,0 +1,98 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Expose the constructor.
10
+ */
11
+
12
+exports = module.exports = Store;
13
+
14
+/**
15
+ * Module dependencies.
16
+ */
17
+
18
+var EventEmitter = process.EventEmitter;
19
+
20
+/**
21
+ * Store interface
22
+ *
23
+ * @api public
24
+ */
25
+
26
+function Store (options) {
27
+  this.options = options;
28
+  this.clients = {};
29
+};
30
+
31
+/**
32
+ * Inherit from EventEmitter.
33
+ */
34
+
35
+Store.prototype.__proto__ = EventEmitter.prototype;
36
+
37
+/**
38
+ * Initializes a client store
39
+ *
40
+ * @param {String} id
41
+ * @api public
42
+ */
43
+
44
+Store.prototype.client = function (id) {
45
+  if (!this.clients[id]) {
46
+    this.clients[id] = new (this.constructor.Client)(this, id);
47
+  }
48
+
49
+  return this.clients[id];
50
+};
51
+
52
+/**
53
+ * Destroys a client
54
+ *
55
+ * @api {String} sid
56
+ * @param {Number} number of seconds to expire client data
57
+ * @api private
58
+ */
59
+
60
+Store.prototype.destroyClient = function (id, expiration) {
61
+  if (this.clients[id]) {
62
+    this.clients[id].destroy(expiration);
63
+    delete this.clients[id];
64
+  }
65
+
66
+  return this;
67
+};
68
+
69
+/**
70
+ * Destroys the store
71
+ *
72
+ * @param {Number} number of seconds to expire client data
73
+ * @api private
74
+ */
75
+
76
+Store.prototype.destroy = function (clientExpiration) {
77
+  var keys = Object.keys(this.clients)
78
+    , count = keys.length;
79
+
80
+  for (var i = 0, l = count; i < l; i++) {
81
+    this.destroyClient(keys[i], clientExpiration);
82
+  }
83
+
84
+  this.clients = {};
85
+
86
+  return this;
87
+};
88
+
89
+/**
90
+ * Client.
91
+ *
92
+ * @api public
93
+ */
94
+
95
+Store.Client = function (store, id) {
96
+  this.store = store;
97
+  this.id = id;
98
+};

+ 143
- 0
node_modules/socket.io/lib/stores/memory.js View File

@@ -0,0 +1,143 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module dependencies.
10
+ */
11
+
12
+var crypto = require('crypto')
13
+  , Store = require('../store');
14
+
15
+/**
16
+ * Exports the constructor.
17
+ */
18
+
19
+exports = module.exports = Memory;
20
+Memory.Client = Client;
21
+
22
+/**
23
+ * Memory store
24
+ *
25
+ * @api public
26
+ */
27
+
28
+function Memory (opts) {
29
+  Store.call(this, opts);
30
+};
31
+
32
+/**
33
+ * Inherits from Store.
34
+ */
35
+
36
+Memory.prototype.__proto__ = Store.prototype;
37
+
38
+/**
39
+ * Publishes a message.
40
+ *
41
+ * @api private
42
+ */
43
+
44
+Memory.prototype.publish = function () { };
45
+
46
+/**
47
+ * Subscribes to a channel
48
+ *
49
+ * @api private
50
+ */
51
+
52
+Memory.prototype.subscribe = function () { };
53
+
54
+/**
55
+ * Unsubscribes
56
+ *
57
+ * @api private
58
+ */
59
+
60
+Memory.prototype.unsubscribe = function () { };
61
+
62
+/**
63
+ * Client constructor
64
+ *
65
+ * @api private
66
+ */
67
+
68
+function Client () {
69
+  Store.Client.apply(this, arguments);
70
+  this.data = {};
71
+};
72
+
73
+/**
74
+ * Inherits from Store.Client
75
+ */
76
+
77
+Client.prototype.__proto__ = Store.Client;
78
+
79
+/**
80
+ * Gets a key
81
+ *
82
+ * @api public
83
+ */
84
+
85
+Client.prototype.get = function (key, fn) {
86
+  fn(null, this.data[key] === undefined ? null : this.data[key]);
87
+  return this;
88
+};
89
+
90
+/**
91
+ * Sets a key
92
+ *
93
+ * @api public
94
+ */
95
+
96
+Client.prototype.set = function (key, value, fn) {
97
+  this.data[key] = value;
98
+  fn && fn(null);
99
+  return this;
100
+};
101
+
102
+/**
103
+ * Has a key
104
+ *
105
+ * @api public
106
+ */
107
+
108
+Client.prototype.has = function (key, fn) {
109
+  fn(null, key in this.data);
110
+};
111
+
112
+/**
113
+ * Deletes a key
114
+ *
115
+ * @api public
116
+ */
117
+
118
+Client.prototype.del = function (key, fn) {
119
+  delete this.data[key];
120
+  fn && fn(null);
121
+  return this;
122
+};
123
+
124
+/**
125
+ * Destroys the client.
126
+ *
127
+ * @param {Number} number of seconds to expire data
128
+ * @api private
129
+ */
130
+
131
+Client.prototype.destroy = function (expiration) {
132
+  if ('number' != typeof expiration) {
133
+    this.data = {};
134
+  } else {
135
+    var self = this;
136
+
137
+    setTimeout(function () {
138
+      self.data = {};
139
+    }, expiration * 1000);
140
+  }
141
+
142
+  return this;
143
+};

+ 269
- 0
node_modules/socket.io/lib/stores/redis.js View File

@@ -0,0 +1,269 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module dependencies.
10
+ */
11
+
12
+var crypto = require('crypto')
13
+  , Store = require('../store')
14
+  , assert = require('assert');
15
+
16
+/**
17
+ * Exports the constructor.
18
+ */
19
+
20
+exports = module.exports = Redis;
21
+Redis.Client = Client;
22
+
23
+/**
24
+ * Redis store.
25
+ * Options:
26
+ *     - nodeId (fn) gets an id that uniquely identifies this node
27
+ *     - redis (fn) redis constructor, defaults to redis
28
+ *     - redisPub (object) options to pass to the pub redis client
29
+ *     - redisSub (object) options to pass to the sub redis client
30
+ *     - redisClient (object) options to pass to the general redis client
31
+ *     - pack (fn) custom packing, defaults to JSON or msgpack if installed
32
+ *     - unpack (fn) custom packing, defaults to JSON or msgpack if installed
33
+ *
34
+ * @api public
35
+ */
36
+
37
+function Redis (opts) {
38
+  opts = opts || {};
39
+
40
+  // node id to uniquely identify this node
41
+  var nodeId = opts.nodeId || function () {
42
+    // by default, we generate a random id 
43
+    return Math.abs(Math.random() * Math.random() * Date.now() | 0);
44
+  };
45
+
46
+  this.nodeId = nodeId();
47
+
48
+  // packing / unpacking mechanism
49
+  if (opts.pack) {
50
+    this.pack = opts.pack;
51
+    this.unpack = opts.unpack;
52
+  } else {
53
+    try {
54
+      var msgpack = require('msgpack');
55
+      this.pack = msgpack.pack;
56
+      this.unpack = msgpack.unpack;
57
+    } catch (e) {
58
+      this.pack = JSON.stringify;
59
+      this.unpack = JSON.parse;
60
+    }
61
+  }
62
+
63
+  var redis = opts.redis || require('redis')
64
+    , RedisClient = redis.RedisClient;
65
+
66
+  // initialize a pubsub client and a regular client
67
+  if (opts.redisPub instanceof RedisClient) {
68
+    this.pub = opts.redisPub;
69
+  } else {
70
+    opts.redisPub || (opts.redisPub = {});
71
+    this.pub = redis.createClient(opts.redisPub.port, opts.redisPub.host, opts.redisPub);
72
+  }
73
+  if (opts.redisSub instanceof RedisClient) {
74
+    this.sub = opts.redisSub;
75
+  } else {
76
+    opts.redisSub || (opts.redisSub = {});
77
+    this.sub = redis.createClient(opts.redisSub.port, opts.redisSub.host, opts.redisSub);
78
+  }
79
+  if (opts.redisClient instanceof RedisClient) {
80
+    this.cmd = opts.redisClient;
81
+  } else {
82
+    opts.redisClient || (opts.redisClient = {});
83
+    this.cmd = redis.createClient(opts.redisClient.port, opts.redisClient.host, opts.redisClient);
84
+  }
85
+
86
+  Store.call(this, opts);
87
+
88
+  this.sub.setMaxListeners(0);
89
+  this.setMaxListeners(0);
90
+};
91
+
92
+/**
93
+ * Inherits from Store.
94
+ */
95
+
96
+Redis.prototype.__proto__ = Store.prototype;
97
+
98
+/**
99
+ * Publishes a message.
100
+ *
101
+ * @api private
102
+ */
103
+
104
+Redis.prototype.publish = function (name) {
105
+  var args = Array.prototype.slice.call(arguments, 1);
106
+  this.pub.publish(name, this.pack({ nodeId: this.nodeId, args: args }));
107
+  this.emit.apply(this, ['publish', name].concat(args));
108
+};
109
+
110
+/**
111
+ * Subscribes to a channel
112
+ *
113
+ * @api private
114
+ */
115
+
116
+Redis.prototype.subscribe = function (name, consumer, fn) {
117
+  this.sub.subscribe(name);
118
+
119
+  if (consumer || fn) {
120
+    var self = this;
121
+
122
+    self.sub.on('subscribe', function subscribe (ch) {
123
+      if (name == ch) {
124
+        function message (ch, msg) {
125
+          if (name == ch) {
126
+            msg = self.unpack(msg);
127
+
128
+            // we check that the message consumed wasnt emitted by this node
129
+            if (self.nodeId != msg.nodeId) {
130
+              consumer.apply(null, msg.args);
131
+            }
132
+          }
133
+        };
134
+
135
+        self.sub.on('message', message);
136
+
137
+        self.on('unsubscribe', function unsubscribe (ch) {
138
+          if (name == ch) {
139
+            self.sub.removeListener('message', message);
140
+            self.removeListener('unsubscribe', unsubscribe);
141
+          }
142
+        });
143
+
144
+        self.sub.removeListener('subscribe', subscribe);
145
+
146
+        fn && fn();
147
+      }
148
+    });
149
+  }
150
+
151
+  this.emit('subscribe', name, consumer, fn);
152
+};
153
+
154
+/**
155
+ * Unsubscribes
156
+ *
157
+ * @api private
158
+ */
159
+
160
+Redis.prototype.unsubscribe = function (name, fn) {
161
+  this.sub.unsubscribe(name);
162
+
163
+  if (fn) {
164
+    var client = this.sub;
165
+
166
+    client.on('unsubscribe', function unsubscribe (ch) {
167
+      if (name == ch) {
168
+        fn();
169
+        client.removeListener('unsubscribe', unsubscribe);
170
+      }
171
+    });
172
+  }
173
+
174
+  this.emit('unsubscribe', name, fn);
175
+};
176
+
177
+/**
178
+ * Destroys the store
179
+ *
180
+ * @api public
181
+ */
182
+
183
+Redis.prototype.destroy = function () {
184
+  Store.prototype.destroy.call(this);
185
+
186
+  this.pub.end();
187
+  this.sub.end();
188
+  this.cmd.end();
189
+};
190
+
191
+/**
192
+ * Client constructor
193
+ *
194
+ * @api private
195
+ */
196
+
197
+function Client (store, id) {
198
+  Store.Client.call(this, store, id);
199
+};
200
+
201
+/**
202
+ * Inherits from Store.Client
203
+ */
204
+
205
+Client.prototype.__proto__ = Store.Client;
206
+
207
+/**
208
+ * Redis hash get
209
+ *
210
+ * @api private
211
+ */
212
+
213
+Client.prototype.get = function (key, fn) {
214
+  this.store.cmd.hget(this.id, key, fn);
215
+  return this;
216
+};
217
+
218
+/**
219
+ * Redis hash set
220
+ *
221
+ * @api private
222
+ */
223
+
224
+Client.prototype.set = function (key, value, fn) {
225
+  this.store.cmd.hset(this.id, key, value, fn);
226
+  return this;
227
+};
228
+
229
+/**
230
+ * Redis hash del
231
+ *
232
+ * @api private
233
+ */
234
+
235
+Client.prototype.del = function (key, fn) {
236
+  this.store.cmd.hdel(this.id, key, fn);
237
+  return this;
238
+};
239
+
240
+/**
241
+ * Redis hash has
242
+ *
243
+ * @api private
244
+ */
245
+
246
+Client.prototype.has = function (key, fn) {
247
+  this.store.cmd.hexists(this.id, key, function (err, has) {
248
+    if (err) return fn(err);
249
+    fn(null, !!has);
250
+  });
251
+  return this;
252
+};
253
+
254
+/**
255
+ * Destroys client
256
+ *
257
+ * @param {Number} number of seconds to expire data
258
+ * @api private
259
+ */
260
+
261
+Client.prototype.destroy = function (expiration) {
262
+  if ('number' != typeof expiration) {
263
+    this.store.cmd.del(this.id);
264
+  } else {
265
+    this.store.cmd.expire(this.id, expiration);
266
+  }
267
+
268
+  return this;
269
+};

+ 534
- 0
node_modules/socket.io/lib/transport.js View File

@@ -0,0 +1,534 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module dependencies.
10
+ */
11
+
12
+var parser = require('./parser');
13
+
14
+/**
15
+ * Expose the constructor.
16
+ */
17
+
18
+exports = module.exports = Transport;
19
+
20
+/**
21
+ * Transport constructor.
22
+ *
23
+ * @api public
24
+ */
25
+
26
+function Transport (mng, data, req) {
27
+  this.manager = mng;
28
+  this.id = data.id;
29
+  this.disconnected = false;
30
+  this.drained = true;
31
+  this.handleRequest(req);
32
+};
33
+
34
+/**
35
+ * Access the logger.
36
+ *
37
+ * @api public
38
+ */
39
+
40
+Transport.prototype.__defineGetter__('log', function () {
41
+  return this.manager.log;
42
+});
43
+
44
+/**
45
+ * Access the store.
46
+ *
47
+ * @api public
48
+ */
49
+
50
+Transport.prototype.__defineGetter__('store', function () {
51
+  return this.manager.store;
52
+});
53
+
54
+/**
55
+ * Handles a request when it's set.
56
+ *
57
+ * @api private
58
+ */
59
+
60
+Transport.prototype.handleRequest = function (req) {
61
+  this.log.debug('setting request', req.method, req.url);
62
+  this.req = req;
63
+
64
+  if (req.method == 'GET') {
65
+    this.socket = req.socket;
66
+    this.open = true;
67
+    this.drained = true;
68
+    this.setHeartbeatInterval();
69
+
70
+    this.setHandlers();
71
+    this.onSocketConnect();
72
+  }
73
+};
74
+
75
+/**
76
+ * Called when a connection is first set.
77
+ *
78
+ * @api private
79
+ */
80
+
81
+Transport.prototype.onSocketConnect = function () { };
82
+
83
+/**
84
+ * Sets transport handlers
85
+ *
86
+ * @api private
87
+ */
88
+
89
+Transport.prototype.setHandlers = function () {
90
+  var self = this;
91
+
92
+  // we need to do this in a pub/sub way since the client can POST the message
93
+  // over a different socket (ie: different Transport instance)
94
+  this.store.subscribe('heartbeat-clear:' + this.id, function () {
95
+    self.onHeartbeatClear();
96
+  });
97
+
98
+  this.store.subscribe('disconnect-force:' + this.id, function () {
99
+    self.onForcedDisconnect();
100
+  });
101
+
102
+  this.store.subscribe('dispatch:' + this.id, function (packet, volatile) {
103
+    self.onDispatch(packet, volatile);
104
+  });
105
+
106
+  this.bound = {
107
+      end: this.onSocketEnd.bind(this)
108
+    , close: this.onSocketClose.bind(this)
109
+    , error: this.onSocketError.bind(this)
110
+    , drain: this.onSocketDrain.bind(this)
111
+  };
112
+
113
+  this.socket.on('end', this.bound.end);
114
+  this.socket.on('close', this.bound.close);
115
+  this.socket.on('error', this.bound.error);
116
+  this.socket.on('drain', this.bound.drain);
117
+
118
+  this.handlersSet = true;
119
+};
120
+
121
+/**
122
+ * Removes transport handlers
123
+ *
124
+ * @api private
125
+ */
126
+
127
+Transport.prototype.clearHandlers = function () {
128
+  if (this.handlersSet) {
129
+    this.store.unsubscribe('disconnect-force:' + this.id);
130
+    this.store.unsubscribe('heartbeat-clear:' + this.id);
131
+    this.store.unsubscribe('dispatch:' + this.id);
132
+
133
+    this.socket.removeListener('end', this.bound.end);
134
+    this.socket.removeListener('close', this.bound.close);
135
+    this.socket.removeListener('error', this.bound.error);
136
+    this.socket.removeListener('drain', this.bound.drain);
137
+  }
138
+};
139
+
140
+/**
141
+ * Called when the connection dies
142
+ *
143
+ * @api private
144
+ */
145
+
146
+Transport.prototype.onSocketEnd = function () {
147
+  this.end('socket end');
148
+};
149
+
150
+/**
151
+ * Called when the connection dies
152
+ *
153
+ * @api private
154
+ */
155
+
156
+Transport.prototype.onSocketClose = function (error) {
157
+  this.end(error ? 'socket error' : 'socket close');
158
+};
159
+
160
+/**
161
+ * Called when the connection has an error.
162
+ *
163
+ * @api private
164
+ */
165
+
166
+Transport.prototype.onSocketError = function (err) {
167
+  if (this.open) {
168
+    this.socket.destroy();
169
+    this.onClose();
170
+  }
171
+
172
+  this.log.info('socket error '  + err.stack);
173
+};
174
+
175
+/**
176
+ * Called when the connection is drained.
177
+ *
178
+ * @api private
179
+ */
180
+
181
+Transport.prototype.onSocketDrain = function () {
182
+  this.drained = true;
183
+};
184
+
185
+/**
186
+ * Called upon receiving a heartbeat packet.
187
+ *
188
+ * @api private
189
+ */
190
+
191
+Transport.prototype.onHeartbeatClear = function () {
192
+  this.clearHeartbeatTimeout();
193
+  this.setHeartbeatInterval();
194
+};
195
+
196
+/**
197
+ * Called upon a forced disconnection.
198
+ *
199
+ * @api private
200
+ */
201
+
202
+Transport.prototype.onForcedDisconnect = function () {
203
+  if (!this.disconnected) {
204
+    this.log.info('transport end by forced client disconnection');
205
+    if (this.open) {
206
+      this.packet({ type: 'disconnect' });
207
+    }
208
+    this.end('booted');
209
+  }
210
+};
211
+
212
+/**
213
+ * Dispatches a packet.
214
+ *
215
+ * @api private
216
+ */
217
+
218
+Transport.prototype.onDispatch = function (packet, volatile) {
219
+  if (volatile) {
220
+    this.writeVolatile(packet);
221
+  } else {
222
+    this.write(packet);
223
+  }
224
+};
225
+
226
+/**
227
+ * Sets the close timeout.
228
+ */
229
+
230
+Transport.prototype.setCloseTimeout = function () {
231
+  if (!this.closeTimeout) {
232
+    var self = this;
233
+
234
+    this.closeTimeout = setTimeout(function () {
235
+      self.log.debug('fired close timeout for client', self.id);
236
+      self.closeTimeout = null;
237
+      self.end('close timeout');
238
+    }, this.manager.get('close timeout') * 1000);
239
+
240
+    this.log.debug('set close timeout for client', this.id);
241
+  }
242
+};
243
+
244
+/**
245
+ * Clears the close timeout.
246
+ */
247
+
248
+Transport.prototype.clearCloseTimeout = function () {
249
+  if (this.closeTimeout) {
250
+    clearTimeout(this.closeTimeout);
251
+    this.closeTimeout = null;
252
+
253
+    this.log.debug('cleared close timeout for client', this.id);
254
+  }
255
+};
256
+
257
+/**
258
+ * Sets the heartbeat timeout
259
+ */
260
+
261
+Transport.prototype.setHeartbeatTimeout = function () {
262
+  if (!this.heartbeatTimeout && this.manager.enabled('heartbeats')) {
263
+    var self = this;
264
+
265
+    this.heartbeatTimeout = setTimeout(function () {
266
+      self.log.debug('fired heartbeat timeout for client', self.id);
267
+      self.heartbeatTimeout = null;
268
+      self.end('heartbeat timeout');
269
+    }, this.manager.get('heartbeat timeout') * 1000);
270
+
271
+    this.log.debug('set heartbeat timeout for client', this.id);
272
+  }
273
+};
274
+
275
+/**
276
+ * Clears the heartbeat timeout
277
+ *
278
+ * @param text
279
+ */
280
+
281
+Transport.prototype.clearHeartbeatTimeout = function () {
282
+  if (this.heartbeatTimeout && this.manager.enabled('heartbeats')) {
283
+    clearTimeout(this.heartbeatTimeout);
284
+    this.heartbeatTimeout = null;
285
+    this.log.debug('cleared heartbeat timeout for client', this.id);
286
+  }
287
+};
288
+
289
+/**
290
+ * Sets the heartbeat interval. To be called when a connection opens and when
291
+ * a heartbeat is received.
292
+ *
293
+ * @api private
294
+ */
295
+
296
+Transport.prototype.setHeartbeatInterval = function () {
297
+  if (!this.heartbeatInterval && this.manager.enabled('heartbeats')) {
298
+    var self = this;
299
+
300
+    this.heartbeatInterval = setTimeout(function () {
301
+      self.heartbeat();
302
+      self.heartbeatInterval = null;
303
+    }, this.manager.get('heartbeat interval') * 1000);
304
+
305
+    this.log.debug('set heartbeat interval for client', this.id);
306
+  }
307
+};
308
+
309
+/**
310
+ * Clears all timeouts.
311
+ *
312
+ * @api private
313
+ */
314
+
315
+Transport.prototype.clearTimeouts = function () {
316
+  this.clearCloseTimeout();
317
+  this.clearHeartbeatTimeout();
318
+  this.clearHeartbeatInterval();
319
+};
320
+
321
+/**
322
+ * Sends a heartbeat
323
+ *
324
+ * @api private
325
+ */
326
+
327
+Transport.prototype.heartbeat = function () {
328
+  if (this.open) {
329
+    this.log.debug('emitting heartbeat for client', this.id);
330
+    this.packet({ type: 'heartbeat' });
331
+    this.setHeartbeatTimeout();
332
+  }
333
+
334
+  return this;
335
+};
336
+
337
+/**
338
+ * Handles a message.
339
+ *
340
+ * @param {Object} packet object
341
+ * @api private
342
+ */
343
+
344
+Transport.prototype.onMessage = function (packet) {
345
+  var current = this.manager.transports[this.id];
346
+
347
+  if ('heartbeat' == packet.type) {
348
+    this.log.debug('got heartbeat packet');
349
+
350
+    if (current && current.open) {
351
+      current.onHeartbeatClear();
352
+    } else {
353
+      this.store.publish('heartbeat-clear:' + this.id);
354
+    }
355
+  } else {
356
+    if ('disconnect' == packet.type && packet.endpoint == '') {
357
+      this.log.debug('got disconnection packet');
358
+
359
+      if (current) {
360
+        current.onForcedDisconnect();
361
+      } else {
362
+        this.store.publish('disconnect-force:' + this.id);
363
+      }
364
+
365
+      return;
366
+    }
367
+
368
+    if (packet.id && packet.ack != 'data') {
369
+      this.log.debug('acknowledging packet automatically');
370
+
371
+      var ack = parser.encodePacket({
372
+          type: 'ack'
373
+        , ackId: packet.id
374
+        , endpoint: packet.endpoint || ''
375
+      });
376
+
377
+      if (current && current.open) {
378
+        current.onDispatch(ack);
379
+      } else {
380
+        this.manager.onClientDispatch(this.id, ack);
381
+        this.store.publish('dispatch:' + this.id, ack);
382
+      }
383
+    }
384
+
385
+    // handle packet locally or publish it
386
+    if (current) {
387
+      this.manager.onClientMessage(this.id, packet);
388
+    } else {
389
+      this.store.publish('message:' + this.id, packet);
390
+    }
391
+  }
392
+};
393
+
394
+/**
395
+ * Clears the heartbeat interval
396
+ *
397
+ * @api private
398
+ */
399
+
400
+Transport.prototype.clearHeartbeatInterval = function () {
401
+  if (this.heartbeatInterval && this.manager.enabled('heartbeats')) {
402
+    clearTimeout(this.heartbeatInterval);
403
+    this.heartbeatInterval = null;
404
+    this.log.debug('cleared heartbeat interval for client', this.id);
405
+  }
406
+};
407
+
408
+/**
409
+ * Finishes the connection and makes sure client doesn't reopen
410
+ *
411
+ * @api private
412
+ */
413
+
414
+Transport.prototype.disconnect = function (reason) {
415
+  this.packet({ type: 'disconnect' });
416
+  this.end(reason);
417
+
418
+  return this;
419
+};
420
+
421
+/**
422
+ * Closes the connection.
423
+ *
424
+ * @api private
425
+ */
426
+
427
+Transport.prototype.close = function () {
428
+  if (this.open) {
429
+    this.doClose();
430
+    this.onClose();
431
+  }
432
+};
433
+
434
+/**
435
+ * Called upon a connection close.
436
+ *
437
+ * @api private
438
+ */
439
+
440
+Transport.prototype.onClose = function () {
441
+  if (this.open) {
442
+    this.setCloseTimeout();
443
+    this.clearHandlers();
444
+    this.open = false;
445
+    this.manager.onClose(this.id);
446
+    this.store.publish('close', this.id);
447
+  }
448
+};
449
+
450
+/**
451
+ * Cleans up the connection, considers the client disconnected.
452
+ *
453
+ * @api private
454
+ */
455
+
456
+Transport.prototype.end = function (reason) {
457
+  if (!this.disconnected) {
458
+    this.log.info('transport end (' + reason + ')');
459
+
460
+    var local = this.manager.transports[this.id];
461
+
462
+    this.close();
463
+    this.clearTimeouts();
464
+    this.disconnected = true;
465
+
466
+    if (local) {
467
+      this.manager.onClientDisconnect(this.id, reason, true);
468
+    } else {
469
+      this.store.publish('disconnect:' + this.id, reason);
470
+    }
471
+  }
472
+};
473
+
474
+/**
475
+ * Signals that the transport should pause and buffer data.
476
+ *
477
+ * @api public
478
+ */
479
+
480
+Transport.prototype.discard = function () {
481
+  this.log.debug('discarding transport');
482
+  this.discarded = true;
483
+  this.clearTimeouts();
484
+  this.clearHandlers();
485
+
486
+  return this;
487
+};
488
+
489
+/**
490
+ * Writes an error packet with the specified reason and advice.
491
+ *
492
+ * @param {Number} advice
493
+ * @param {Number} reason
494
+ * @api public
495
+ */
496
+
497
+Transport.prototype.error = function (reason, advice) {
498
+  this.packet({
499
+      type: 'error'
500
+    , reason: reason
501
+    , advice: advice
502
+  });
503
+
504
+  this.log.warn(reason, advice ? ('client should ' + advice) : '');
505
+  this.end('error');
506
+};
507
+
508
+/**
509
+ * Write a packet.
510
+ *
511
+ * @api public
512
+ */
513
+
514
+Transport.prototype.packet = function (obj) {
515
+  return this.write(parser.encodePacket(obj));
516
+};
517
+
518
+/**
519
+ * Writes a volatile message.
520
+ *
521
+ * @api private
522
+ */
523
+
524
+Transport.prototype.writeVolatile = function (msg) {
525
+  if (this.open) {
526
+    if (this.drained) {
527
+      this.write(msg);
528
+    } else {
529
+      this.log.debug('ignoring volatile packet, buffer not drained');
530
+    }
531
+  } else {
532
+    this.log.debug('ignoring volatile packet, transport not open');
533
+  }
534
+};

+ 129
- 0
node_modules/socket.io/lib/transports/flashsocket.js View File

@@ -0,0 +1,129 @@
1
+/*!
2
+ * socket.io-node
3
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
4
+ * MIT Licensed
5
+ */
6
+
7
+/**
8
+ * Module requirements.
9
+ */
10
+var WebSocket = require('./websocket');
11
+
12
+/**
13
+ * Export the constructor.
14
+ */
15
+
16
+exports = module.exports = FlashSocket;
17
+
18
+/**
19
+ * The FlashSocket transport is just a proxy
20
+ * for WebSocket connections.
21
+ *
22
+ * @api public
23
+ */
24
+ 
25
+function FlashSocket (mng, data, req) {
26
+  return WebSocket.call(this, mng, data, req);
27
+}
28
+
29
+/**
30
+ * Inherits from WebSocket.
31
+ */
32
+
33
+FlashSocket.prototype.__proto__ = WebSocket.prototype;
34
+
35
+/**
36
+ * Transport name
37
+ *
38
+ * @api public
39
+ */
40
+
41
+FlashSocket.prototype.name = 'flashsocket';
42
+
43
+/**
44
+ * Listens for new configuration changes of the Manager
45
+ * this way we can enable and disable the flash server.
46
+ *
47
+ * @param {Manager} Manager instance.
48
+ * @api private
49
+ */
50
+
51
+
52
+FlashSocket.init = function (manager) {
53
+  var server;
54
+  function create () {
55
+
56
+    // Drop out immediately if the user has
57
+    // disabled the flash policy server
58
+    if (!manager.get('flash policy server')) {
59
+      return;
60
+    }
61
+
62
+    server = require('policyfile').createServer({ 
63
+      log: function(msg){
64
+        manager.log.info(msg);
65
+      }
66
+    }, manager.get('origins'));
67
+
68
+    server.on('close', function (e) {
69
+      server = null;
70
+    });
71
+
72
+    server.listen(manager.get('flash policy port'), manager.server);
73
+
74
+    manager.flashPolicyServer = server;
75
+  }
76
+
77
+  // listen for origin changes, so we can update the server
78
+  manager.on('set:origins', function (value, key) {
79
+    if (!server) return;
80
+
81
+    // update the origins and compile a new response buffer
82
+    server.origins = Array.isArray(value) ? value : [value];
83
+    server.compile();
84
+  });
85
+
86
+  // destory the server and create a new server
87
+  manager.on('set:flash policy port', function (value, key) {
88
+    var transports = manager.get('transports');
89
+    if (~transports.indexOf('flashsocket')) {
90
+      if (server) {
91
+        if (server.port === value) return;
92
+        // destroy the server and rebuild it on a new port
93
+        try {
94
+          server.close();
95
+        }
96
+        catch (e) { /* ignore exception. could e.g. be that the server isn't started yet */ }
97
+      }
98
+      create();
99
+    }
100
+  });
101
+
102
+  // create or destroy the server
103
+  manager.on('set:flash policy server', function (value, key) {
104
+    var transports = manager.get('transports');
105
+    if (~transports.indexOf('flashsocket')) {
106
+      if (server && !value) {
107
+        // destroy the server
108
+        try {
109
+          server.close();
110
+        }
111
+        catch (e) { /* ignore exception. could e.g. be that the server isn't started yet */ }
112
+      }
113
+    } else if (!server && value) {
114
+      // create the server
115
+      create();
116
+    }
117
+  });
118
+
119
+  // only start the server
120
+  manager.on('set:transports', function (value, key){
121
+    if (!server && ~manager.get('transports').indexOf('flashsocket')) {
122
+      create();
123
+    }
124
+  });
125
+  // check if we need to initialize at start
126
+  if (~manager.get('transports').indexOf('flashsocket')){
127
+    create();
128
+  }
129
+};

+ 83
- 0
node_modules/socket.io/lib/transports/htmlfile.js View File

@@ -0,0 +1,83 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module requirements.
10
+ */
11
+
12
+var HTTPTransport = require('./http');
13
+
14
+/**
15
+ * Export the constructor.
16
+ */
17
+
18
+exports = module.exports = HTMLFile;
19
+
20
+/**
21
+ * HTMLFile transport constructor.
22
+ *
23
+ * @api public
24
+ */
25
+
26
+function HTMLFile (mng, data, req) {
27
+  HTTPTransport.call(this, mng, data, req);
28
+};
29
+
30
+/**
31
+ * Inherits from Transport.
32
+ */
33
+
34
+HTMLFile.prototype.__proto__ = HTTPTransport.prototype;
35
+
36
+/**
37
+ * Transport name
38
+ *
39
+ * @api public
40
+ */
41
+
42
+HTMLFile.prototype.name = 'htmlfile';
43
+
44
+/**
45
+ * Handles the request.
46
+ *
47
+ * @api private
48
+ */
49
+
50
+HTMLFile.prototype.handleRequest = function (req) {
51
+  HTTPTransport.prototype.handleRequest.call(this, req);
52
+
53
+  if (req.method == 'GET') {
54
+    req.res.writeHead(200, {
55
+        'Content-Type': 'text/html; charset=UTF-8'
56
+      , 'Connection': 'keep-alive'
57
+      , 'Transfer-Encoding': 'chunked'
58
+    });
59
+
60
+    req.res.write(
61
+        '<html><body>'
62
+      + '<script>var _ = function (msg) { parent.s._(msg, document); };</script>'
63
+      + new Array(174).join(' ')
64
+    );
65
+  }
66
+};
67
+
68
+/**
69
+ * Performs the write.
70
+ *
71
+ * @api private
72
+ */
73
+
74
+HTMLFile.prototype.write = function (data) {
75
+  // escape all forward slashes. see GH-1251
76
+  data = '<script>_(' + JSON.stringify(data).replace(/\//g, '\\/') + ');</script>';
77
+
78
+  if (this.response.write(data)) {
79
+    this.drained = true;
80
+  }
81
+
82
+  this.log.debug(this.name + ' writing', data);
83
+};

+ 147
- 0
node_modules/socket.io/lib/transports/http-polling.js View File

@@ -0,0 +1,147 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module requirements.
10
+ */
11
+
12
+var HTTPTransport = require('./http');
13
+
14
+/**
15
+ * Exports the constructor.
16
+ */
17
+
18
+exports = module.exports = HTTPPolling;
19
+
20
+/**
21
+ * HTTP polling constructor.
22
+ *
23
+ * @api public.
24
+ */
25
+
26
+function HTTPPolling (mng, data, req) {
27
+  HTTPTransport.call(this, mng, data, req);
28
+};
29
+
30
+/**
31
+ * Inherits from HTTPTransport.
32
+ *
33
+ * @api public.
34
+ */
35
+
36
+HTTPPolling.prototype.__proto__ = HTTPTransport.prototype;
37
+
38
+/**
39
+ * Transport name
40
+ *
41
+ * @api public
42
+ */
43
+
44
+HTTPPolling.prototype.name = 'httppolling';
45
+
46
+/**
47
+ * Override setHandlers
48
+ *
49
+ * @api private
50
+ */
51
+
52
+HTTPPolling.prototype.setHandlers = function () {
53
+  HTTPTransport.prototype.setHandlers.call(this);
54
+  this.socket.removeListener('end', this.bound.end);
55
+  this.socket.removeListener('close', this.bound.close);
56
+};
57
+
58
+/**
59
+ * Removes heartbeat timeouts for polling.
60
+ */
61
+
62
+HTTPPolling.prototype.setHeartbeatInterval = function () {
63
+  return this;
64
+};
65
+
66
+/**
67
+ * Handles a request
68
+ *
69
+ * @api private
70
+ */
71
+
72
+HTTPPolling.prototype.handleRequest = function (req) {
73
+  HTTPTransport.prototype.handleRequest.call(this, req);
74
+
75
+  if (req.method == 'GET') {
76
+    var self = this;
77
+
78
+    this.pollTimeout = setTimeout(function () {
79
+      self.packet({ type: 'noop' });
80
+      self.log.debug(self.name + ' closed due to exceeded duration');
81
+    }, this.manager.get('polling duration') * 1000);
82
+
83
+    this.log.debug('setting poll timeout');
84
+  }
85
+};
86
+
87
+/**
88
+ * Clears polling timeout
89
+ *
90
+ * @api private
91
+ */
92
+
93
+HTTPPolling.prototype.clearPollTimeout = function () {
94
+  if (this.pollTimeout) {
95
+    clearTimeout(this.pollTimeout);
96
+    this.pollTimeout = null;
97
+    this.log.debug('clearing poll timeout');
98
+  }
99
+
100
+  return this;
101
+};
102
+
103
+/**
104
+ * Override clear timeouts to clear the poll timeout
105
+ *
106
+ * @api private
107
+ */
108
+
109
+HTTPPolling.prototype.clearTimeouts = function () {
110
+  HTTPTransport.prototype.clearTimeouts.call(this);
111
+
112
+  this.clearPollTimeout();
113
+};
114
+
115
+/**
116
+ * doWrite to clear poll timeout
117
+ *
118
+ * @api private
119
+ */
120
+
121
+HTTPPolling.prototype.doWrite = function () {
122
+  this.clearPollTimeout();
123
+};
124
+
125
+/**
126
+ * Performs a write.
127
+ *
128
+ * @api private.
129
+ */
130
+
131
+HTTPPolling.prototype.write = function (data, close) {
132
+  this.doWrite(data);
133
+  this.response.end();
134
+  this.onClose();
135
+};
136
+
137
+/**
138
+ * Override end.
139
+ *
140
+ * @api private
141
+ */
142
+
143
+HTTPPolling.prototype.end = function (reason) {
144
+  this.clearPollTimeout();
145
+  return HTTPTransport.prototype.end.call(this, reason);
146
+};
147
+

+ 121
- 0
node_modules/socket.io/lib/transports/http.js View File

@@ -0,0 +1,121 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module requirements.
10
+ */
11
+
12
+var Transport = require('../transport')
13
+  , parser = require('../parser')
14
+  , qs = require('querystring');
15
+
16
+/**
17
+ * Export the constructor.
18
+ */
19
+
20
+exports = module.exports = HTTPTransport;
21
+
22
+/**
23
+ * HTTP interface constructor. For all non-websocket transports.
24
+ *
25
+ * @api public
26
+ */
27
+
28
+function HTTPTransport (mng, data, req) {
29
+  Transport.call(this, mng, data, req);
30
+};
31
+
32
+/**
33
+ * Inherits from Transport.
34
+ */
35
+
36
+HTTPTransport.prototype.__proto__ = Transport.prototype;
37
+
38
+/**
39
+ * Handles a request.
40
+ *
41
+ * @api private
42
+ */
43
+
44
+HTTPTransport.prototype.handleRequest = function (req) {
45
+
46
+  // Always set the response in case an error is returned to the client
47
+  this.response = req.res;
48
+
49
+  if (req.method == 'POST') {
50
+    var buffer = ''
51
+      , res = req.res
52
+      , origin = req.headers.origin
53
+      , headers = { 'Content-Length': 1, 'Content-Type': 'text/plain; charset=UTF-8' }
54
+      , self = this;
55
+
56
+    req.on('data', function (data) {
57
+      buffer += data;
58
+
59
+      if (Buffer.byteLength(buffer) >= self.manager.get('destroy buffer size')) {
60
+        buffer = '';
61
+        req.connection.destroy();
62
+      }
63
+    });
64
+
65
+    req.on('end', function () {
66
+      res.writeHead(200, headers);
67
+      res.end('1');
68
+
69
+      self.onData(self.postEncoded ? qs.parse(buffer).d : buffer);
70
+    });
71
+
72
+    // prevent memory leaks for uncompleted requests
73
+    req.on('close', function () {
74
+      buffer = '';
75
+      self.onClose();
76
+    });
77
+
78
+    if (origin) {
79
+      // https://developer.mozilla.org/En/HTTP_Access_Control
80
+      headers['Access-Control-Allow-Origin'] = origin;
81
+      headers['Access-Control-Allow-Credentials'] = 'true';
82
+    }
83
+  } else {
84
+    Transport.prototype.handleRequest.call(this, req);
85
+  }
86
+};
87
+
88
+/**
89
+ * Handles data payload.
90
+ *
91
+ * @api private
92
+ */
93
+
94
+HTTPTransport.prototype.onData = function (data) {
95
+  var messages = parser.decodePayload(data);
96
+  this.log.debug(this.name + ' received data packet', data);
97
+
98
+  for (var i = 0, l = messages.length; i < l; i++) {
99
+    this.onMessage(messages[i]);
100
+  }
101
+};
102
+
103
+/**
104
+ * Closes the request-response cycle
105
+ *
106
+ * @api private
107
+ */
108
+
109
+HTTPTransport.prototype.doClose = function () {
110
+  this.response.end();
111
+};
112
+
113
+/**
114
+ * Writes a payload of messages
115
+ *
116
+ * @api private
117
+ */
118
+
119
+HTTPTransport.prototype.payload = function (msgs) {
120
+  this.write(parser.encodePayload(msgs));
121
+};

+ 12
- 0
node_modules/socket.io/lib/transports/index.js View File

@@ -0,0 +1,12 @@
1
+
2
+/**
3
+ * Export transports.
4
+ */
5
+
6
+module.exports = {
7
+    websocket: require('./websocket')
8
+  , flashsocket: require('./flashsocket')
9
+  , htmlfile: require('./htmlfile')
10
+  , 'xhr-polling': require('./xhr-polling')
11
+  , 'jsonp-polling': require('./jsonp-polling')
12
+};

+ 97
- 0
node_modules/socket.io/lib/transports/jsonp-polling.js View File

@@ -0,0 +1,97 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module requirements.
10
+ */
11
+
12
+var HTTPPolling = require('./http-polling');
13
+var jsonpolling_re = /^\d+$/
14
+
15
+/**
16
+ * Export the constructor.
17
+ */
18
+
19
+exports = module.exports = JSONPPolling;
20
+
21
+/**
22
+ * JSON-P polling transport.
23
+ *
24
+ * @api public
25
+ */
26
+
27
+function JSONPPolling (mng, data, req) {
28
+  HTTPPolling.call(this, mng, data, req);
29
+
30
+  this.head = 'io.j[0](';
31
+  this.foot = ');';
32
+
33
+  if (data.query.i && jsonpolling_re.test(data.query.i)) {
34
+    this.head = 'io.j[' + data.query.i + '](';
35
+  }
36
+};
37
+
38
+/**
39
+ * Inherits from Transport.
40
+ */
41
+
42
+JSONPPolling.prototype.__proto__ = HTTPPolling.prototype;
43
+
44
+/**
45
+ * Transport name
46
+ *
47
+ * @api public
48
+ */
49
+
50
+JSONPPolling.prototype.name = 'jsonppolling';
51
+
52
+/**
53
+ * Make sure POST are decoded.
54
+ */
55
+
56
+JSONPPolling.prototype.postEncoded = true;
57
+
58
+/**
59
+ * Handles incoming data.
60
+ * Due to a bug in \n handling by browsers, we expect a JSONified string.
61
+ *
62
+ * @api private
63
+ */
64
+
65
+JSONPPolling.prototype.onData = function (data) {
66
+  try {
67
+    data = JSON.parse(data);
68
+  } catch (e) {
69
+    this.error('parse', 'reconnect');
70
+    return;
71
+  }
72
+
73
+  HTTPPolling.prototype.onData.call(this, data);
74
+};
75
+
76
+/**
77
+ * Performs the write.
78
+ *
79
+ * @api private
80
+ */
81
+
82
+JSONPPolling.prototype.doWrite = function (data) {
83
+  HTTPPolling.prototype.doWrite.call(this);
84
+
85
+  var data = data === undefined
86
+      ? '' : this.head + JSON.stringify(data) + this.foot;
87
+
88
+  this.response.writeHead(200, {
89
+      'Content-Type': 'text/javascript; charset=UTF-8'
90
+    , 'Content-Length': Buffer.byteLength(data)
91
+    , 'Connection': 'Keep-Alive'
92
+    , 'X-XSS-Protection': '0'
93
+  });
94
+
95
+  this.response.write(data);
96
+  this.log.debug(this.name + ' writing', data);
97
+};

+ 36
- 0
node_modules/socket.io/lib/transports/websocket.js View File

@@ -0,0 +1,36 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module requirements.
10
+ */
11
+
12
+var protocolVersions = require('./websocket/');
13
+
14
+/**
15
+ * Export the constructor.
16
+ */
17
+
18
+exports = module.exports = WebSocket;
19
+
20
+/**
21
+ * HTTP interface constructor. Interface compatible with all transports that
22
+ * depend on request-response cycles.
23
+ *
24
+ * @api public
25
+ */
26
+
27
+function WebSocket (mng, data, req) {
28
+  var transport
29
+    , version = req.headers['sec-websocket-version'];
30
+  if (typeof version !== 'undefined' && typeof protocolVersions[version] !== 'undefined') {
31
+    transport = new protocolVersions[version](mng, data, req);
32
+  }
33
+  else transport = new protocolVersions['default'](mng, data, req);
34
+  if (typeof this.name !== 'undefined') transport.name = this.name;
35
+  return transport;
36
+};

+ 362
- 0
node_modules/socket.io/lib/transports/websocket/default.js View File

@@ -0,0 +1,362 @@
1
+/*!
2
+ * socket.io-node
3
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
4
+ * MIT Licensed
5
+ */
6
+
7
+/**
8
+ * Module requirements.
9
+ */
10
+
11
+var Transport = require('../../transport')
12
+  , EventEmitter = process.EventEmitter
13
+  , crypto = require('crypto')
14
+  , parser = require('../../parser');
15
+
16
+/**
17
+ * Export the constructor.
18
+ */
19
+
20
+exports = module.exports = WebSocket;
21
+
22
+/**
23
+ * HTTP interface constructor. Interface compatible with all transports that
24
+ * depend on request-response cycles.
25
+ *
26
+ * @api public
27
+ */
28
+
29
+function WebSocket (mng, data, req) {
30
+  // parser
31
+  var self = this;
32
+
33
+  this.parser = new Parser();
34
+  this.parser.on('data', function (packet) {
35
+    self.log.debug(self.name + ' received data packet', packet);
36
+    self.onMessage(parser.decodePacket(packet));
37
+  });
38
+  this.parser.on('close', function () {
39
+    self.end();
40
+  });
41
+  this.parser.on('error', function () {
42
+    self.end();
43
+  });
44
+
45
+  Transport.call(this, mng, data, req);
46
+};
47
+
48
+/**
49
+ * Inherits from Transport.
50
+ */
51
+
52
+WebSocket.prototype.__proto__ = Transport.prototype;
53
+
54
+/**
55
+ * Transport name
56
+ *
57
+ * @api public
58
+ */
59
+
60
+WebSocket.prototype.name = 'websocket';
61
+
62
+/**
63
+ * Websocket draft version
64
+ *
65
+ * @api public
66
+ */
67
+
68
+WebSocket.prototype.protocolVersion = 'hixie-76';
69
+
70
+/**
71
+ * Called when the socket connects.
72
+ *
73
+ * @api private
74
+ */
75
+
76
+WebSocket.prototype.onSocketConnect = function () {
77
+  var self = this;
78
+
79
+  this.socket.setNoDelay(true);
80
+
81
+  this.buffer = true;
82
+  this.buffered = [];
83
+
84
+  if (this.req.headers.upgrade !== 'WebSocket') {
85
+    this.log.warn(this.name + ' connection invalid');
86
+    this.end();
87
+    return;
88
+  }
89
+
90
+  var origin = this.req.headers['origin']
91
+  , waitingForNonce = false;
92
+  if(this.manager.settings['match origin protocol']){
93
+    location = (origin.indexOf('https')>-1 ? 'wss' : 'ws') + '://' + this.req.headers.host + this.req.url;
94
+  }else if(this.socket.encrypted){
95
+    location = 'wss://' + this.req.headers.host + this.req.url;
96
+  }else{
97
+    location = 'ws://' + this.req.headers.host + this.req.url;
98
+  }
99
+
100
+  if (this.req.headers['sec-websocket-key1']) {
101
+    // If we don't have the nonce yet, wait for it (HAProxy compatibility).
102
+    if (! (this.req.head && this.req.head.length >= 8)) {
103
+      waitingForNonce = true;
104
+    }
105
+
106
+    var headers = [
107
+        'HTTP/1.1 101 WebSocket Protocol Handshake'
108
+      , 'Upgrade: WebSocket'
109
+      , 'Connection: Upgrade'
110
+      , 'Sec-WebSocket-Origin: ' + origin
111
+      , 'Sec-WebSocket-Location: ' + location
112
+    ];
113
+
114
+    if (this.req.headers['sec-websocket-protocol']){
115
+      headers.push('Sec-WebSocket-Protocol: '
116
+          + this.req.headers['sec-websocket-protocol']);
117
+    }
118
+  } else {
119
+    var headers = [
120
+        'HTTP/1.1 101 Web Socket Protocol Handshake'
121
+      , 'Upgrade: WebSocket'
122
+      , 'Connection: Upgrade'
123
+      , 'WebSocket-Origin: ' + origin
124
+      , 'WebSocket-Location: ' + location
125
+    ];
126
+  }
127
+
128
+  try {
129
+    this.socket.write(headers.concat('', '').join('\r\n'));
130
+    this.socket.setTimeout(0);
131
+    this.socket.setNoDelay(true);
132
+    this.socket.setEncoding('utf8');
133
+  } catch (e) {
134
+    this.end();
135
+    return;
136
+  }
137
+
138
+  if (waitingForNonce) {
139
+    this.socket.setEncoding('binary');
140
+  } else if (this.proveReception(headers)) {
141
+    self.flush();
142
+  }
143
+
144
+  var headBuffer = '';
145
+
146
+  this.socket.on('data', function (data) {
147
+    if (waitingForNonce) {
148
+      headBuffer += data;
149
+
150
+      if (headBuffer.length < 8) {
151
+        return;
152
+      }
153
+
154
+      // Restore the connection to utf8 encoding after receiving the nonce
155
+      self.socket.setEncoding('utf8');
156
+      waitingForNonce = false;
157
+
158
+      // Stuff the nonce into the location where it's expected to be
159
+      self.req.head = headBuffer.substr(0, 8);
160
+      headBuffer = '';
161
+
162
+      if (self.proveReception(headers)) {
163
+        self.flush();
164
+      }
165
+
166
+      return;
167
+    }
168
+
169
+    self.parser.add(data);
170
+  });
171
+};
172
+
173
+/**
174
+ * Writes to the socket.
175
+ *
176
+ * @api private
177
+ */
178
+
179
+WebSocket.prototype.write = function (data) {
180
+  if (this.open) {
181
+    this.drained = false;
182
+
183
+    if (this.buffer) {
184
+      this.buffered.push(data);
185
+      return this;
186
+    }
187
+
188
+    var length = Buffer.byteLength(data)
189
+      , buffer = new Buffer(2 + length);
190
+
191
+    buffer.write('\x00', 'binary');
192
+    buffer.write(data, 1, 'utf8');
193
+    buffer.write('\xff', 1 + length, 'binary');
194
+
195
+    try {
196
+      if (this.socket.write(buffer)) {
197
+        this.drained = true;
198
+      }
199
+    } catch (e) {
200
+      this.end();
201
+    }
202
+
203
+    this.log.debug(this.name + ' writing', data);
204
+  }
205
+};
206
+
207
+/**
208
+ * Flushes the internal buffer
209
+ *
210
+ * @api private
211
+ */
212
+
213
+WebSocket.prototype.flush = function () {
214
+  this.buffer = false;
215
+
216
+  for (var i = 0, l = this.buffered.length; i < l; i++) {
217
+    this.write(this.buffered.splice(0, 1)[0]);
218
+  }
219
+};
220
+
221
+/**
222
+ * Finishes the handshake.
223
+ *
224
+ * @api private
225
+ */
226
+
227
+WebSocket.prototype.proveReception = function (headers) {
228
+  var self = this
229
+    , k1 = this.req.headers['sec-websocket-key1']
230
+    , k2 = this.req.headers['sec-websocket-key2'];
231
+
232
+  if (k1 && k2){
233
+    var md5 = crypto.createHash('md5');
234
+
235
+    [k1, k2].forEach(function (k) {
236
+      var n = parseInt(k.replace(/[^\d]/g, ''))
237
+        , spaces = k.replace(/[^ ]/g, '').length;
238
+
239
+      if (spaces === 0 || n % spaces !== 0){
240
+        self.log.warn('Invalid ' + self.name + ' key: "' + k + '".');
241
+        self.end();
242
+        return false;
243
+      }
244
+
245
+      n /= spaces;
246
+
247
+      md5.update(String.fromCharCode(
248
+        n >> 24 & 0xFF,
249
+        n >> 16 & 0xFF,
250
+        n >> 8  & 0xFF,
251
+        n       & 0xFF));
252
+    });
253
+
254
+    md5.update(this.req.head.toString('binary'));
255
+
256
+    try {
257
+      this.socket.write(md5.digest('binary'), 'binary');
258
+    } catch (e) {
259
+      this.end();
260
+    }
261
+  }
262
+
263
+  return true;
264
+};
265
+
266
+/**
267
+ * Writes a payload.
268
+ *
269
+ * @api private
270
+ */
271
+
272
+WebSocket.prototype.payload = function (msgs) {
273
+  for (var i = 0, l = msgs.length; i < l; i++) {
274
+    this.write(msgs[i]);
275
+  }
276
+
277
+  return this;
278
+};
279
+
280
+/**
281
+ * Closes the connection.
282
+ *
283
+ * @api private
284
+ */
285
+
286
+WebSocket.prototype.doClose = function () {
287
+  this.socket.end();
288
+};
289
+
290
+/**
291
+ * WebSocket parser
292
+ *
293
+ * @api public
294
+ */
295
+
296
+function Parser () {
297
+  this.buffer = '';
298
+  this.i = 0;
299
+};
300
+
301
+/**
302
+ * Inherits from EventEmitter.
303
+ */
304
+
305
+Parser.prototype.__proto__ = EventEmitter.prototype;
306
+
307
+/**
308
+ * Adds data to the buffer.
309
+ *
310
+ * @api public
311
+ */
312
+
313
+Parser.prototype.add = function (data) {
314
+  this.buffer += data;
315
+  this.parse();
316
+};
317
+
318
+/**
319
+ * Parses the buffer.
320
+ *
321
+ * @api private
322
+ */
323
+
324
+Parser.prototype.parse = function () {
325
+  for (var i = this.i, chr, l = this.buffer.length; i < l; i++){
326
+    chr = this.buffer[i];
327
+
328
+    if (this.buffer.length == 2 && this.buffer[1] == '\u0000') {
329
+      this.emit('close');
330
+      this.buffer = '';
331
+      this.i = 0;
332
+      return;
333
+    }
334
+
335
+    if (i === 0){
336
+      if (chr != '\u0000')
337
+        this.error('Bad framing. Expected null byte as first frame');
338
+      else
339
+        continue;
340
+    }
341
+
342
+    if (chr == '\ufffd'){
343
+      this.emit('data', this.buffer.substr(1, i - 1));
344
+      this.buffer = this.buffer.substr(i + 1);
345
+      this.i = 0;
346
+      return this.parse();
347
+    }
348
+  }
349
+};
350
+
351
+/**
352
+ * Handles an error
353
+ *
354
+ * @api private
355
+ */
356
+
357
+Parser.prototype.error = function (reason) {
358
+  this.buffer = '';
359
+  this.i = 0;
360
+  this.emit('error', reason);
361
+  return this;
362
+};

+ 622
- 0
node_modules/socket.io/lib/transports/websocket/hybi-07-12.js View File

@@ -0,0 +1,622 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+ 
8
+/**
9
+ * Module requirements.
10
+ */
11
+
12
+var Transport = require('../../transport')
13
+  , EventEmitter = process.EventEmitter
14
+  , crypto = require('crypto')
15
+  , url = require('url')
16
+  , parser = require('../../parser')
17
+  , util = require('../../util');
18
+
19
+/**
20
+ * Export the constructor.
21
+ */
22
+
23
+exports = module.exports = WebSocket;
24
+exports.Parser = Parser;
25
+
26
+/**
27
+ * HTTP interface constructor. Interface compatible with all transports that
28
+ * depend on request-response cycles.
29
+ *
30
+ * @api public
31
+ */
32
+
33
+function WebSocket (mng, data, req) {
34
+  // parser
35
+  var self = this;
36
+
37
+  this.manager = mng;
38
+  this.parser = new Parser();
39
+  this.parser.on('data', function (packet) {
40
+    self.onMessage(parser.decodePacket(packet));
41
+  });
42
+  this.parser.on('ping', function () {
43
+    // version 8 ping => pong
44
+    try {
45
+      self.socket.write('\u008a\u0000');
46
+    }
47
+    catch (e) {
48
+      self.end();
49
+      return;
50
+    }
51
+  });
52
+  this.parser.on('close', function () {
53
+    self.end();
54
+  });
55
+  this.parser.on('error', function (reason) {
56
+    self.log.warn(self.name + ' parser error: ' + reason);
57
+    self.end();
58
+  });
59
+
60
+  Transport.call(this, mng, data, req);
61
+};
62
+
63
+/**
64
+ * Inherits from Transport.
65
+ */
66
+
67
+WebSocket.prototype.__proto__ = Transport.prototype;
68
+
69
+/**
70
+ * Transport name
71
+ *
72
+ * @api public
73
+ */
74
+
75
+WebSocket.prototype.name = 'websocket';
76
+
77
+/**
78
+ * Websocket draft version
79
+ *
80
+ * @api public
81
+ */
82
+
83
+WebSocket.prototype.protocolVersion = '07-12';
84
+
85
+/**
86
+ * Called when the socket connects.
87
+ *
88
+ * @api private
89
+ */
90
+
91
+WebSocket.prototype.onSocketConnect = function () {
92
+  var self = this;
93
+
94
+  if (typeof this.req.headers.upgrade === 'undefined' || 
95
+      this.req.headers.upgrade.toLowerCase() !== 'websocket') {
96
+    this.log.warn(this.name + ' connection invalid');
97
+    this.end();
98
+    return;
99
+  }
100
+
101
+  var origin = this.req.headers['sec-websocket-origin']
102
+    , location = ((this.manager.settings['match origin protocol'] ?
103
+                      origin.match(/^https/) : this.socket.encrypted) ?
104
+                        'wss' : 'ws')
105
+               + '://' + this.req.headers.host + this.req.url;
106
+  
107
+  if (!this.verifyOrigin(origin)) {
108
+    this.log.warn(this.name + ' connection invalid: origin mismatch');
109
+    this.end();
110
+    return;    
111
+  }
112
+  
113
+  if (!this.req.headers['sec-websocket-key']) {
114
+    this.log.warn(this.name + ' connection invalid: received no key');
115
+    this.end();
116
+    return;
117
+  }
118
+    
119
+  // calc key
120
+  var key = this.req.headers['sec-websocket-key'];  
121
+  var shasum = crypto.createHash('sha1');  
122
+  shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");  
123
+  key = shasum.digest('base64');
124
+
125
+  var headers = [
126
+      'HTTP/1.1 101 Switching Protocols'
127
+    , 'Upgrade: websocket'
128
+    , 'Connection: Upgrade'
129
+    , 'Sec-WebSocket-Accept: ' + key
130
+  ];
131
+
132
+  try {
133
+    this.socket.write(headers.concat('', '').join('\r\n'));
134
+    this.socket.setTimeout(0);
135
+    this.socket.setNoDelay(true);
136
+  } catch (e) {
137
+    this.end();
138
+    return;
139
+  }
140
+
141
+  this.socket.on('data', function (data) {
142
+    self.parser.add(data);
143
+  });
144
+};
145
+
146
+/**
147
+ * Verifies the origin of a request.
148
+ *
149
+ * @api private
150
+ */
151
+
152
+WebSocket.prototype.verifyOrigin = function (origin) {
153
+  var origins = this.manager.get('origins');
154
+
155
+  if (origin === 'null') origin = '*';
156
+
157
+  if (origins.indexOf('*:*') !== -1) {
158
+    return true;
159
+  }
160
+
161
+  if (origin) {
162
+    try {
163
+      var parts = url.parse(origin);
164
+      parts.port = parts.port || 80;
165
+      var ok =
166
+        ~origins.indexOf(parts.hostname + ':' + parts.port) ||
167
+        ~origins.indexOf(parts.hostname + ':*') ||
168
+        ~origins.indexOf('*:' + parts.port);
169
+      if (!ok) this.log.warn('illegal origin: ' + origin);
170
+      return ok;
171
+    } catch (ex) {
172
+      this.log.warn('error parsing origin');
173
+    }
174
+  }
175
+  else {
176
+    this.log.warn('origin missing from websocket call, yet required by config');        
177
+  }
178
+  return false;
179
+};
180
+
181
+/**
182
+ * Writes to the socket.
183
+ *
184
+ * @api private
185
+ */
186
+
187
+WebSocket.prototype.write = function (data) {
188
+  if (this.open) {
189
+    var buf = this.frame(0x81, data);
190
+    try {
191
+      this.socket.write(buf, 'binary');
192
+    }
193
+    catch (e) {
194
+      this.end();
195
+      return;
196
+    }
197
+    this.log.debug(this.name + ' writing', data);
198
+  }
199
+};
200
+
201
+/**
202
+ * Writes a payload.
203
+ *
204
+ * @api private
205
+ */
206
+
207
+WebSocket.prototype.payload = function (msgs) {
208
+  for (var i = 0, l = msgs.length; i < l; i++) {
209
+    this.write(msgs[i]);
210
+  }
211
+
212
+  return this;
213
+};
214
+
215
+/**
216
+ * Frame server-to-client output as a text packet.
217
+ *
218
+ * @api private
219
+ */
220
+
221
+WebSocket.prototype.frame = function (opcode, str) {
222
+  var dataBuffer = new Buffer(str)
223
+    , dataLength = dataBuffer.length
224
+    , startOffset = 2
225
+    , secondByte = dataLength;
226
+  if (dataLength > 65536) {
227
+    startOffset = 10;
228
+    secondByte = 127;
229
+  }
230
+  else if (dataLength > 125) {
231
+    startOffset = 4;
232
+    secondByte = 126;
233
+  }
234
+  var outputBuffer = new Buffer(dataLength + startOffset);
235
+  outputBuffer[0] = opcode;
236
+  outputBuffer[1] = secondByte;
237
+  dataBuffer.copy(outputBuffer, startOffset);
238
+  switch (secondByte) {
239
+  case 126:
240
+    outputBuffer[2] = dataLength >>> 8;
241
+    outputBuffer[3] = dataLength % 256;
242
+    break;
243
+  case 127:
244
+    var l = dataLength;
245
+    for (var i = 1; i <= 8; ++i) {
246
+      outputBuffer[startOffset - i] = l & 0xff;
247
+      l >>>= 8;
248
+    }
249
+  }
250
+  return outputBuffer;
251
+};
252
+
253
+/**
254
+ * Closes the connection.
255
+ *
256
+ * @api private
257
+ */
258
+
259
+WebSocket.prototype.doClose = function () {
260
+  this.socket.end();
261
+};
262
+
263
+/**
264
+ * WebSocket parser
265
+ *
266
+ * @api public
267
+ */
268
+ 
269
+function Parser () {
270
+  this.state = {
271
+    activeFragmentedOperation: null,
272
+    lastFragment: false,
273
+    masked: false,
274
+    opcode: 0
275
+  };
276
+  this.overflow = null;
277
+  this.expectOffset = 0;
278
+  this.expectBuffer = null;
279
+  this.expectHandler = null;
280
+  this.currentMessage = '';
281
+
282
+  var self = this;  
283
+  this.opcodeHandlers = {
284
+    // text
285
+    '1': function(data) {
286
+      var finish = function(mask, data) {
287
+        self.currentMessage += self.unmask(mask, data);
288
+        if (self.state.lastFragment) {
289
+          self.emit('data', self.currentMessage);
290
+          self.currentMessage = '';
291
+        }
292
+        self.endPacket();
293
+      }
294
+
295
+      var expectData = function(length) {
296
+        if (self.state.masked) {
297
+          self.expect('Mask', 4, function(data) {
298
+            var mask = data;
299
+            self.expect('Data', length, function(data) {
300
+              finish(mask, data);
301
+            });
302
+          });
303
+        }
304
+        else {
305
+          self.expect('Data', length, function(data) { 
306
+            finish(null, data);
307
+          });
308
+        } 
309
+      }
310
+
311
+      // decode length
312
+      var firstLength = data[1] & 0x7f;
313
+      if (firstLength < 126) {
314
+        expectData(firstLength);
315
+      }
316
+      else if (firstLength == 126) {
317
+        self.expect('Length', 2, function(data) {
318
+          expectData(util.unpack(data));
319
+        });
320
+      }
321
+      else if (firstLength == 127) {
322
+        self.expect('Length', 8, function(data) {
323
+          if (util.unpack(data.slice(0, 4)) != 0) {
324
+            self.error('packets with length spanning more than 32 bit is currently not supported');
325
+            return;
326
+          }
327
+          var lengthBytes = data.slice(4); // note: cap to 32 bit length
328
+          expectData(util.unpack(data));
329
+        });
330
+      }      
331
+    },
332
+    // binary
333
+    '2': function(data) {
334
+      var finish = function(mask, data) {
335
+        if (typeof self.currentMessage == 'string') self.currentMessage = []; // build a buffer list
336
+        self.currentMessage.push(self.unmask(mask, data, true));
337
+        if (self.state.lastFragment) {
338
+          self.emit('binary', self.concatBuffers(self.currentMessage));
339
+          self.currentMessage = '';
340
+        }
341
+        self.endPacket();
342
+      }
343
+
344
+      var expectData = function(length) {
345
+        if (self.state.masked) {
346
+          self.expect('Mask', 4, function(data) {
347
+            var mask = data;
348
+            self.expect('Data', length, function(data) {
349
+              finish(mask, data);
350
+            });
351
+          });
352
+        }
353
+        else {
354
+          self.expect('Data', length, function(data) { 
355
+            finish(null, data);
356
+          });
357
+        } 
358
+      }
359
+
360
+      // decode length
361
+      var firstLength = data[1] & 0x7f;
362
+      if (firstLength < 126) {
363
+        expectData(firstLength);
364
+      }
365
+      else if (firstLength == 126) {
366
+        self.expect('Length', 2, function(data) {
367
+          expectData(util.unpack(data));
368
+        });
369
+      }
370
+      else if (firstLength == 127) {
371
+        self.expect('Length', 8, function(data) {
372
+          if (util.unpack(data.slice(0, 4)) != 0) {
373
+            self.error('packets with length spanning more than 32 bit is currently not supported');
374
+            return;
375
+          }
376
+          var lengthBytes = data.slice(4); // note: cap to 32 bit length
377
+          expectData(util.unpack(data));
378
+        });
379
+      }      
380
+    },
381
+    // close
382
+    '8': function(data) {
383
+      self.emit('close');
384
+      self.reset();
385
+    },
386
+    // ping
387
+    '9': function(data) {
388
+      if (self.state.lastFragment == false) {
389
+        self.error('fragmented ping is not supported');
390
+        return;
391
+      }
392
+      
393
+      var finish = function(mask, data) {
394
+        self.emit('ping', self.unmask(mask, data));
395
+        self.endPacket();
396
+      }
397
+
398
+      var expectData = function(length) {
399
+        if (self.state.masked) {
400
+          self.expect('Mask', 4, function(data) {
401
+            var mask = data;
402
+            self.expect('Data', length, function(data) {
403
+              finish(mask, data);
404
+            });
405
+          });
406
+        }
407
+        else {
408
+          self.expect('Data', length, function(data) { 
409
+            finish(null, data);
410
+          });
411
+        } 
412
+      }
413
+
414
+      // decode length
415
+      var firstLength = data[1] & 0x7f;
416
+      if (firstLength == 0) {
417
+        finish(null, null);        
418
+      }
419
+      else if (firstLength < 126) {
420
+        expectData(firstLength);
421
+      }
422
+      else if (firstLength == 126) {
423
+        self.expect('Length', 2, function(data) {
424
+          expectData(util.unpack(data));
425
+        });
426
+      }
427
+      else if (firstLength == 127) {
428
+        self.expect('Length', 8, function(data) {
429
+          expectData(util.unpack(data));
430
+        });
431
+      }      
432
+    }
433
+  }
434
+
435
+  this.expect('Opcode', 2, this.processPacket);  
436
+};
437
+
438
+/**
439
+ * Inherits from EventEmitter.
440
+ */
441
+
442
+Parser.prototype.__proto__ = EventEmitter.prototype;
443
+
444
+/**
445
+ * Add new data to the parser.
446
+ *
447
+ * @api public
448
+ */
449
+
450
+Parser.prototype.add = function(data) {
451
+  if (this.expectBuffer == null) {
452
+    this.addToOverflow(data);
453
+    return;
454
+  }
455
+  var toRead = Math.min(data.length, this.expectBuffer.length - this.expectOffset);
456
+  data.copy(this.expectBuffer, this.expectOffset, 0, toRead);
457
+  this.expectOffset += toRead;
458
+  if (toRead < data.length) {
459
+    // at this point the overflow buffer shouldn't at all exist
460
+    this.overflow = new Buffer(data.length - toRead);
461
+    data.copy(this.overflow, 0, toRead, toRead + this.overflow.length);
462
+  }
463
+  if (this.expectOffset == this.expectBuffer.length) {
464
+    var bufferForHandler = this.expectBuffer;
465
+    this.expectBuffer = null;
466
+    this.expectOffset = 0;
467
+    this.expectHandler.call(this, bufferForHandler);
468
+  }
469
+}
470
+
471
+/**
472
+ * Adds a piece of data to the overflow.
473
+ *
474
+ * @api private
475
+ */
476
+
477
+Parser.prototype.addToOverflow = function(data) {
478
+  if (this.overflow == null) this.overflow = data;
479
+  else {
480
+    var prevOverflow = this.overflow;
481
+    this.overflow = new Buffer(this.overflow.length + data.length);
482
+    prevOverflow.copy(this.overflow, 0);
483
+    data.copy(this.overflow, prevOverflow.length);
484
+  }  
485
+}
486
+
487
+/**
488
+ * Waits for a certain amount of bytes to be available, then fires a callback.
489
+ *
490
+ * @api private
491
+ */
492
+
493
+Parser.prototype.expect = function(what, length, handler) {
494
+  this.expectBuffer = new Buffer(length);
495
+  this.expectOffset = 0;
496
+  this.expectHandler = handler;
497
+  if (this.overflow != null) {
498
+    var toOverflow = this.overflow;
499
+    this.overflow = null;
500
+    this.add(toOverflow);
501
+  }
502
+}
503
+
504
+/**
505
+ * Start processing a new packet.
506
+ *
507
+ * @api private
508
+ */
509
+
510
+Parser.prototype.processPacket = function (data) {
511
+  if ((data[0] & 0x70) != 0) {
512
+    this.error('reserved fields must be empty');
513
+  }
514
+  this.state.lastFragment = (data[0] & 0x80) == 0x80; 
515
+  this.state.masked = (data[1] & 0x80) == 0x80;
516
+  var opcode = data[0] & 0xf;
517
+  if (opcode == 0) { 
518
+    // continuation frame
519
+    this.state.opcode = this.state.activeFragmentedOperation;
520
+    if (!(this.state.opcode == 1 || this.state.opcode == 2)) {
521
+      this.error('continuation frame cannot follow current opcode')
522
+      return;
523
+    }
524
+  }
525
+  else {    
526
+    this.state.opcode = opcode;
527
+    if (this.state.lastFragment === false) {
528
+        this.state.activeFragmentedOperation = opcode;
529
+    }
530
+  }
531
+  var handler = this.opcodeHandlers[this.state.opcode];
532
+  if (typeof handler == 'undefined') this.error('no handler for opcode ' + this.state.opcode);
533
+  else handler(data);
534
+}
535
+
536
+/**
537
+ * Endprocessing a packet.
538
+ *
539
+ * @api private
540
+ */
541
+
542
+Parser.prototype.endPacket = function() {
543
+  this.expectOffset = 0;
544
+  this.expectBuffer = null;
545
+  this.expectHandler = null;
546
+  if (this.state.lastFragment && this.state.opcode == this.state.activeFragmentedOperation) {
547
+    // end current fragmented operation
548
+    this.state.activeFragmentedOperation = null;
549
+  }
550
+  this.state.lastFragment = false;
551
+  this.state.opcode = this.state.activeFragmentedOperation != null ? this.state.activeFragmentedOperation : 0;
552
+  this.state.masked = false;
553
+  this.expect('Opcode', 2, this.processPacket);  
554
+}
555
+
556
+/**
557
+ * Reset the parser state.
558
+ *
559
+ * @api private
560
+ */
561
+
562
+Parser.prototype.reset = function() {
563
+  this.state = {
564
+    activeFragmentedOperation: null,
565
+    lastFragment: false,
566
+    masked: false,
567
+    opcode: 0
568
+  };
569
+  this.expectOffset = 0;
570
+  this.expectBuffer = null;
571
+  this.expectHandler = null;
572
+  this.overflow = null;
573
+  this.currentMessage = '';
574
+}
575
+
576
+/**
577
+ * Unmask received data.
578
+ *
579
+ * @api private
580
+ */
581
+
582
+Parser.prototype.unmask = function (mask, buf, binary) {
583
+  if (mask != null) {
584
+    for (var i = 0, ll = buf.length; i < ll; i++) {
585
+      buf[i] ^= mask[i % 4];
586
+    }    
587
+  }
588
+  if (binary) return buf;
589
+  return buf != null ? buf.toString('utf8') : '';
590
+}
591
+
592
+/**
593
+ * Concatenates a list of buffers.
594
+ *
595
+ * @api private
596
+ */
597
+
598
+Parser.prototype.concatBuffers = function(buffers) {
599
+  var length = 0;
600
+  for (var i = 0, l = buffers.length; i < l; ++i) {
601
+    length += buffers[i].length;
602
+  }
603
+  var mergedBuffer = new Buffer(length);
604
+  var offset = 0;
605
+  for (var i = 0, l = buffers.length; i < l; ++i) {
606
+    buffers[i].copy(mergedBuffer, offset);
607
+    offset += buffers[i].length;
608
+  }
609
+  return mergedBuffer;
610
+}
611
+
612
+/**
613
+ * Handles an error
614
+ *
615
+ * @api private
616
+ */
617
+
618
+Parser.prototype.error = function (reason) {
619
+  this.reset();
620
+  this.emit('error', reason);
621
+  return this;
622
+};

+ 622
- 0
node_modules/socket.io/lib/transports/websocket/hybi-16.js View File

@@ -0,0 +1,622 @@
1
+/*!
2
+ * socket.io-node
3
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
4
+ * MIT Licensed
5
+ */
6
+ 
7
+/**
8
+ * Module requirements.
9
+ */
10
+
11
+var Transport = require('../../transport')
12
+  , EventEmitter = process.EventEmitter
13
+  , crypto = require('crypto')
14
+  , url = require('url')
15
+  , parser = require('../../parser')
16
+  , util = require('../../util');
17
+
18
+/**
19
+ * Export the constructor.
20
+ */
21
+
22
+exports = module.exports = WebSocket;
23
+exports.Parser = Parser;
24
+
25
+/**
26
+ * HTTP interface constructor. Interface compatible with all transports that
27
+ * depend on request-response cycles.
28
+ *
29
+ * @api public
30
+ */
31
+
32
+function WebSocket (mng, data, req) {
33
+  // parser
34
+  var self = this;
35
+
36
+  this.manager = mng;
37
+  this.parser = new Parser();
38
+  this.parser.on('data', function (packet) {
39
+    self.onMessage(parser.decodePacket(packet));
40
+  });
41
+  this.parser.on('ping', function () {
42
+    // version 8 ping => pong
43
+    try {
44
+      self.socket.write('\u008a\u0000');
45
+    }
46
+    catch (e) {
47
+      self.end();
48
+      return;
49
+    }
50
+  });
51
+  this.parser.on('close', function () {
52
+    self.end();
53
+  });
54
+  this.parser.on('error', function (reason) {
55
+    self.log.warn(self.name + ' parser error: ' + reason);
56
+    self.end();
57
+  });
58
+
59
+  Transport.call(this, mng, data, req);
60
+};
61
+
62
+/**
63
+ * Inherits from Transport.
64
+ */
65
+
66
+WebSocket.prototype.__proto__ = Transport.prototype;
67
+
68
+/**
69
+ * Transport name
70
+ *
71
+ * @api public
72
+ */
73
+
74
+WebSocket.prototype.name = 'websocket';
75
+
76
+/**
77
+ * Websocket draft version
78
+ *
79
+ * @api public
80
+ */
81
+
82
+WebSocket.prototype.protocolVersion = '16';
83
+
84
+/**
85
+ * Called when the socket connects.
86
+ *
87
+ * @api private
88
+ */
89
+
90
+WebSocket.prototype.onSocketConnect = function () {
91
+  var self = this;
92
+
93
+  if (typeof this.req.headers.upgrade === 'undefined' || 
94
+      this.req.headers.upgrade.toLowerCase() !== 'websocket') {
95
+    this.log.warn(this.name + ' connection invalid');
96
+    this.end();
97
+    return;
98
+  }
99
+
100
+  var origin = this.req.headers['origin'] || ''
101
+    , location = ((this.manager.settings['match origin protocol'] ?
102
+                      origin.match(/^https/) : this.socket.encrypted) ?
103
+                        'wss' : 'ws')
104
+               + '://' + this.req.headers.host + this.req.url;
105
+  
106
+  if (!this.verifyOrigin(origin)) {
107
+    this.log.warn(this.name + ' connection invalid: origin mismatch');
108
+    this.end();
109
+    return;    
110
+  }
111
+  
112
+  if (!this.req.headers['sec-websocket-key']) {
113
+    this.log.warn(this.name + ' connection invalid: received no key');
114
+    this.end();
115
+    return;
116
+  }
117
+    
118
+  // calc key
119
+  var key = this.req.headers['sec-websocket-key'];  
120
+  var shasum = crypto.createHash('sha1');  
121
+  shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");  
122
+  key = shasum.digest('base64');
123
+
124
+  var headers = [
125
+      'HTTP/1.1 101 Switching Protocols'
126
+    , 'Upgrade: websocket'
127
+    , 'Connection: Upgrade'
128
+    , 'Sec-WebSocket-Accept: ' + key
129
+  ];
130
+
131
+  try {
132
+    this.socket.write(headers.concat('', '').join('\r\n'));
133
+    this.socket.setTimeout(0);
134
+    this.socket.setNoDelay(true);
135
+  } catch (e) {
136
+    this.end();
137
+    return;
138
+  }
139
+
140
+  this.socket.on('data', function (data) {
141
+    self.parser.add(data);
142
+  });
143
+};
144
+
145
+/**
146
+ * Verifies the origin of a request.
147
+ *
148
+ * @api private
149
+ */
150
+
151
+WebSocket.prototype.verifyOrigin = function (origin) {
152
+  var origins = this.manager.get('origins');
153
+
154
+  if (origin === 'null') origin = '*';
155
+
156
+  if (origins.indexOf('*:*') !== -1) {
157
+    return true;
158
+  }
159
+
160
+  if (origin) {
161
+    try {
162
+      var parts = url.parse(origin);
163
+      parts.port = parts.port || 80;
164
+      var ok =
165
+        ~origins.indexOf(parts.hostname + ':' + parts.port) ||
166
+        ~origins.indexOf(parts.hostname + ':*') ||
167
+        ~origins.indexOf('*:' + parts.port);
168
+      if (!ok) this.log.warn('illegal origin: ' + origin);
169
+      return ok;
170
+    } catch (ex) {
171
+      this.log.warn('error parsing origin');
172
+    }
173
+  }
174
+  else {
175
+    this.log.warn('origin missing from websocket call, yet required by config');        
176
+  }
177
+  return false;
178
+};
179
+
180
+/**
181
+ * Writes to the socket.
182
+ *
183
+ * @api private
184
+ */
185
+
186
+WebSocket.prototype.write = function (data) {
187
+  if (this.open) {
188
+    var buf = this.frame(0x81, data);
189
+    try {
190
+      this.socket.write(buf, 'binary');
191
+    }
192
+    catch (e) {
193
+      this.end();
194
+      return;
195
+    }
196
+    this.log.debug(this.name + ' writing', data);
197
+  }
198
+};
199
+
200
+/**
201
+ * Writes a payload.
202
+ *
203
+ * @api private
204
+ */
205
+
206
+WebSocket.prototype.payload = function (msgs) {
207
+  for (var i = 0, l = msgs.length; i < l; i++) {
208
+    this.write(msgs[i]);
209
+  }
210
+
211
+  return this;
212
+};
213
+
214
+/**
215
+ * Frame server-to-client output as a text packet.
216
+ *
217
+ * @api private
218
+ */
219
+
220
+WebSocket.prototype.frame = function (opcode, str) {
221
+  var dataBuffer = new Buffer(str)
222
+    , dataLength = dataBuffer.length
223
+    , startOffset = 2
224
+    , secondByte = dataLength;
225
+  if (dataLength > 65536) {
226
+    startOffset = 10;
227
+    secondByte = 127;
228
+  }
229
+  else if (dataLength > 125) {
230
+    startOffset = 4;
231
+    secondByte = 126;
232
+  }
233
+  var outputBuffer = new Buffer(dataLength + startOffset);
234
+  outputBuffer[0] = opcode;
235
+  outputBuffer[1] = secondByte;
236
+  dataBuffer.copy(outputBuffer, startOffset);
237
+  switch (secondByte) {
238
+  case 126:
239
+    outputBuffer[2] = dataLength >>> 8;
240
+    outputBuffer[3] = dataLength % 256;
241
+    break;
242
+  case 127:
243
+    var l = dataLength;
244
+    for (var i = 1; i <= 8; ++i) {
245
+      outputBuffer[startOffset - i] = l & 0xff;
246
+      l >>>= 8;
247
+    }
248
+  }
249
+  return outputBuffer;
250
+};
251
+
252
+/**
253
+ * Closes the connection.
254
+ *
255
+ * @api private
256
+ */
257
+
258
+WebSocket.prototype.doClose = function () {
259
+  this.socket.end();
260
+};
261
+
262
+/**
263
+ * WebSocket parser
264
+ *
265
+ * @api public
266
+ */
267
+ 
268
+function Parser () {
269
+  this.state = {
270
+    activeFragmentedOperation: null,
271
+    lastFragment: false,
272
+    masked: false,
273
+    opcode: 0
274
+  };
275
+  this.overflow = null;
276
+  this.expectOffset = 0;
277
+  this.expectBuffer = null;
278
+  this.expectHandler = null;
279
+  this.currentMessage = '';
280
+
281
+  var self = this;  
282
+  this.opcodeHandlers = {
283
+    // text
284
+    '1': function(data) {
285
+      var finish = function(mask, data) {
286
+        self.currentMessage += self.unmask(mask, data);
287
+        if (self.state.lastFragment) {
288
+          self.emit('data', self.currentMessage);
289
+          self.currentMessage = '';
290
+        }
291
+        self.endPacket();
292
+      }
293
+
294
+      var expectData = function(length) {
295
+        if (self.state.masked) {
296
+          self.expect('Mask', 4, function(data) {
297
+            var mask = data;
298
+            self.expect('Data', length, function(data) {
299
+              finish(mask, data);
300
+            });
301
+          });
302
+        }
303
+        else {
304
+          self.expect('Data', length, function(data) { 
305
+            finish(null, data);
306
+          });
307
+        } 
308
+      }
309
+
310
+      // decode length
311
+      var firstLength = data[1] & 0x7f;
312
+      if (firstLength < 126) {
313
+        expectData(firstLength);
314
+      }
315
+      else if (firstLength == 126) {
316
+        self.expect('Length', 2, function(data) {
317
+          expectData(util.unpack(data));
318
+        });
319
+      }
320
+      else if (firstLength == 127) {
321
+        self.expect('Length', 8, function(data) {
322
+          if (util.unpack(data.slice(0, 4)) != 0) {
323
+            self.error('packets with length spanning more than 32 bit is currently not supported');
324
+            return;
325
+          }
326
+          var lengthBytes = data.slice(4); // note: cap to 32 bit length
327
+          expectData(util.unpack(data));
328
+        });
329
+      }      
330
+    },
331
+    // binary
332
+    '2': function(data) {
333
+      var finish = function(mask, data) {
334
+        if (typeof self.currentMessage == 'string') self.currentMessage = []; // build a buffer list
335
+        self.currentMessage.push(self.unmask(mask, data, true));
336
+        if (self.state.lastFragment) {
337
+          self.emit('binary', self.concatBuffers(self.currentMessage));
338
+          self.currentMessage = '';
339
+        }
340
+        self.endPacket();
341
+      }
342
+
343
+      var expectData = function(length) {
344
+        if (self.state.masked) {
345
+          self.expect('Mask', 4, function(data) {
346
+            var mask = data;
347
+            self.expect('Data', length, function(data) {
348
+              finish(mask, data);
349
+            });
350
+          });
351
+        }
352
+        else {
353
+          self.expect('Data', length, function(data) { 
354
+            finish(null, data);
355
+          });
356
+        } 
357
+      }
358
+
359
+      // decode length
360
+      var firstLength = data[1] & 0x7f;
361
+      if (firstLength < 126) {
362
+        expectData(firstLength);
363
+      }
364
+      else if (firstLength == 126) {
365
+        self.expect('Length', 2, function(data) {
366
+          expectData(util.unpack(data));
367
+        });
368
+      }
369
+      else if (firstLength == 127) {
370
+        self.expect('Length', 8, function(data) {
371
+          if (util.unpack(data.slice(0, 4)) != 0) {
372
+            self.error('packets with length spanning more than 32 bit is currently not supported');
373
+            return;
374
+          }
375
+          var lengthBytes = data.slice(4); // note: cap to 32 bit length
376
+          expectData(util.unpack(data));
377
+        });
378
+      }      
379
+    },
380
+    // close
381
+    '8': function(data) {
382
+      self.emit('close');
383
+      self.reset();
384
+    },
385
+    // ping
386
+    '9': function(data) {
387
+      if (self.state.lastFragment == false) {
388
+        self.error('fragmented ping is not supported');
389
+        return;
390
+      }
391
+      
392
+      var finish = function(mask, data) {
393
+        self.emit('ping', self.unmask(mask, data));
394
+        self.endPacket();
395
+      }
396
+
397
+      var expectData = function(length) {
398
+        if (self.state.masked) {
399
+          self.expect('Mask', 4, function(data) {
400
+            var mask = data;
401
+            self.expect('Data', length, function(data) {
402
+              finish(mask, data);
403
+            });
404
+          });
405
+        }
406
+        else {
407
+          self.expect('Data', length, function(data) { 
408
+            finish(null, data);
409
+          });
410
+        } 
411
+      }
412
+
413
+      // decode length
414
+      var firstLength = data[1] & 0x7f;
415
+      if (firstLength == 0) {
416
+        finish(null, null);        
417
+      }
418
+      else if (firstLength < 126) {
419
+        expectData(firstLength);
420
+      }
421
+      else if (firstLength == 126) {
422
+        self.expect('Length', 2, function(data) {
423
+          expectData(util.unpack(data));
424
+        });
425
+      }
426
+      else if (firstLength == 127) {
427
+        self.expect('Length', 8, function(data) {
428
+          expectData(util.unpack(data));
429
+        });
430
+      }      
431
+    }
432
+  }
433
+
434
+  this.expect('Opcode', 2, this.processPacket);  
435
+};
436
+
437
+/**
438
+ * Inherits from EventEmitter.
439
+ */
440
+
441
+Parser.prototype.__proto__ = EventEmitter.prototype;
442
+
443
+/**
444
+ * Add new data to the parser.
445
+ *
446
+ * @api public
447
+ */
448
+
449
+Parser.prototype.add = function(data) {
450
+  if (this.expectBuffer == null) {
451
+    this.addToOverflow(data);
452
+    return;
453
+  }
454
+  var toRead = Math.min(data.length, this.expectBuffer.length - this.expectOffset);
455
+  data.copy(this.expectBuffer, this.expectOffset, 0, toRead);
456
+  this.expectOffset += toRead;
457
+  if (toRead < data.length) {
458
+    // at this point the overflow buffer shouldn't at all exist
459
+    this.overflow = new Buffer(data.length - toRead);
460
+    data.copy(this.overflow, 0, toRead, toRead + this.overflow.length);
461
+  }
462
+  if (this.expectOffset == this.expectBuffer.length) {
463
+    var bufferForHandler = this.expectBuffer;
464
+    this.expectBuffer = null;
465
+    this.expectOffset = 0;
466
+    this.expectHandler.call(this, bufferForHandler);
467
+  }
468
+}
469
+
470
+/**
471
+ * Adds a piece of data to the overflow.
472
+ *
473
+ * @api private
474
+ */
475
+
476
+Parser.prototype.addToOverflow = function(data) {
477
+  if (this.overflow == null) this.overflow = data;
478
+  else {
479
+    var prevOverflow = this.overflow;
480
+    this.overflow = new Buffer(this.overflow.length + data.length);
481
+    prevOverflow.copy(this.overflow, 0);
482
+    data.copy(this.overflow, prevOverflow.length);
483
+  }  
484
+}
485
+
486
+/**
487
+ * Waits for a certain amount of bytes to be available, then fires a callback.
488
+ *
489
+ * @api private
490
+ */
491
+
492
+Parser.prototype.expect = function(what, length, handler) {
493
+  this.expectBuffer = new Buffer(length);
494
+  this.expectOffset = 0;
495
+  this.expectHandler = handler;
496
+  if (this.overflow != null) {
497
+    var toOverflow = this.overflow;
498
+    this.overflow = null;
499
+    this.add(toOverflow);
500
+  }
501
+}
502
+
503
+/**
504
+ * Start processing a new packet.
505
+ *
506
+ * @api private
507
+ */
508
+
509
+Parser.prototype.processPacket = function (data) {
510
+  if ((data[0] & 0x70) != 0) {
511
+    this.error('reserved fields must be empty');
512
+    return;
513
+  } 
514
+  this.state.lastFragment = (data[0] & 0x80) == 0x80; 
515
+  this.state.masked = (data[1] & 0x80) == 0x80;
516
+  var opcode = data[0] & 0xf;
517
+  if (opcode == 0) { 
518
+    // continuation frame
519
+    this.state.opcode = this.state.activeFragmentedOperation;
520
+    if (!(this.state.opcode == 1 || this.state.opcode == 2)) {
521
+      this.error('continuation frame cannot follow current opcode')
522
+      return;
523
+    }
524
+  }
525
+  else {    
526
+    this.state.opcode = opcode;
527
+    if (this.state.lastFragment === false) {
528
+        this.state.activeFragmentedOperation = opcode;
529
+    }
530
+  }
531
+  var handler = this.opcodeHandlers[this.state.opcode];
532
+  if (typeof handler == 'undefined') this.error('no handler for opcode ' + this.state.opcode);
533
+  else handler(data);
534
+}
535
+
536
+/**
537
+ * Endprocessing a packet.
538
+ *
539
+ * @api private
540
+ */
541
+
542
+Parser.prototype.endPacket = function() {
543
+  this.expectOffset = 0;
544
+  this.expectBuffer = null;
545
+  this.expectHandler = null;
546
+  if (this.state.lastFragment && this.state.opcode == this.state.activeFragmentedOperation) {
547
+    // end current fragmented operation
548
+    this.state.activeFragmentedOperation = null;
549
+  }
550
+  this.state.lastFragment = false;
551
+  this.state.opcode = this.state.activeFragmentedOperation != null ? this.state.activeFragmentedOperation : 0;
552
+  this.state.masked = false;
553
+  this.expect('Opcode', 2, this.processPacket);  
554
+}
555
+
556
+/**
557
+ * Reset the parser state.
558
+ *
559
+ * @api private
560
+ */
561
+
562
+Parser.prototype.reset = function() {
563
+  this.state = {
564
+    activeFragmentedOperation: null,
565
+    lastFragment: false,
566
+    masked: false,
567
+    opcode: 0
568
+  };
569
+  this.expectOffset = 0;
570
+  this.expectBuffer = null;
571
+  this.expectHandler = null;
572
+  this.overflow = null;
573
+  this.currentMessage = '';
574
+}
575
+
576
+/**
577
+ * Unmask received data.
578
+ *
579
+ * @api private
580
+ */
581
+
582
+Parser.prototype.unmask = function (mask, buf, binary) {
583
+  if (mask != null) {
584
+    for (var i = 0, ll = buf.length; i < ll; i++) {
585
+      buf[i] ^= mask[i % 4];
586
+    }    
587
+  }
588
+  if (binary) return buf;
589
+  return buf != null ? buf.toString('utf8') : '';
590
+}
591
+
592
+/**
593
+ * Concatenates a list of buffers.
594
+ *
595
+ * @api private
596
+ */
597
+
598
+Parser.prototype.concatBuffers = function(buffers) {
599
+  var length = 0;
600
+  for (var i = 0, l = buffers.length; i < l; ++i) {
601
+    length += buffers[i].length;
602
+  }
603
+  var mergedBuffer = new Buffer(length);
604
+  var offset = 0;
605
+  for (var i = 0, l = buffers.length; i < l; ++i) {
606
+    buffers[i].copy(mergedBuffer, offset);
607
+    offset += buffers[i].length;
608
+  }
609
+  return mergedBuffer;
610
+}
611
+
612
+/**
613
+ * Handles an error
614
+ *
615
+ * @api private
616
+ */
617
+
618
+Parser.prototype.error = function (reason) {
619
+  this.reset();
620
+  this.emit('error', reason);
621
+  return this;
622
+};

+ 11
- 0
node_modules/socket.io/lib/transports/websocket/index.js View File

@@ -0,0 +1,11 @@
1
+
2
+/**
3
+ * Export websocket versions.
4
+ */
5
+
6
+module.exports = {
7
+  7: require('./hybi-07-12'),
8
+  8: require('./hybi-07-12'),
9
+  13: require('./hybi-16'),
10
+  default: require('./default')
11
+};

+ 69
- 0
node_modules/socket.io/lib/transports/xhr-polling.js View File

@@ -0,0 +1,69 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module requirements.
10
+ */
11
+
12
+var HTTPPolling = require('./http-polling');
13
+
14
+/**
15
+ * Export the constructor.
16
+ */
17
+
18
+exports = module.exports = XHRPolling;
19
+
20
+/**
21
+ * Ajax polling transport.
22
+ *
23
+ * @api public
24
+ */
25
+
26
+function XHRPolling (mng, data, req) {
27
+  HTTPPolling.call(this, mng, data, req);
28
+};
29
+
30
+/**
31
+ * Inherits from Transport.
32
+ */
33
+
34
+XHRPolling.prototype.__proto__ = HTTPPolling.prototype;
35
+
36
+/**
37
+ * Transport name
38
+ *
39
+ * @api public
40
+ */
41
+
42
+XHRPolling.prototype.name = 'xhr-polling';
43
+
44
+/**
45
+ * Frames data prior to write.
46
+ *
47
+ * @api private
48
+ */
49
+
50
+XHRPolling.prototype.doWrite = function (data) {
51
+  HTTPPolling.prototype.doWrite.call(this);
52
+
53
+  var origin = this.req.headers.origin
54
+    , headers = {
55
+          'Content-Type': 'text/plain; charset=UTF-8'
56
+        , 'Content-Length': data === undefined ? 0 : Buffer.byteLength(data)
57
+        , 'Connection': 'Keep-Alive'
58
+      };
59
+
60
+  if (origin) {
61
+    // https://developer.mozilla.org/En/HTTP_Access_Control
62
+    headers['Access-Control-Allow-Origin'] = origin;
63
+    headers['Access-Control-Allow-Credentials'] = 'true';
64
+  }
65
+
66
+  this.response.writeHead(200, headers);
67
+  this.response.write(data);
68
+  this.log.debug(this.name + ' writing', data);
69
+};

+ 50
- 0
node_modules/socket.io/lib/util.js View File

@@ -0,0 +1,50 @@
1
+
2
+/*!
3
+ * socket.io-node
4
+ * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+/**
9
+ * Module dependencies.
10
+ */
11
+
12
+/**
13
+ * Converts an enumerable to an array.
14
+ *
15
+ * @api public
16
+ */
17
+
18
+exports.toArray = function (enu) {
19
+  var arr = [];
20
+
21
+  for (var i = 0, l = enu.length; i < l; i++)
22
+    arr.push(enu[i]);
23
+
24
+  return arr;
25
+};
26
+
27
+/**
28
+ * Unpacks a buffer to a number.
29
+ *
30
+ * @api public
31
+ */
32
+
33
+exports.unpack = function (buffer) {
34
+  var n = 0;
35
+  for (var i = 0; i < buffer.length; ++i) {
36
+    n = (i == 0) ? buffer[i] : (n * 256) + buffer[i];
37
+  }
38
+  return n;
39
+}
40
+
41
+/**
42
+ * Left pads a string.
43
+ *
44
+ * @api public
45
+ */
46
+
47
+exports.padl = function (s,n,c) { 
48
+  return new Array(1 + n - s.length).join(c) + s;
49
+}
50
+

+ 3
- 0
node_modules/socket.io/node_modules/base64id/.npmignore View File

@@ -0,0 +1,3 @@
1
+support
2
+test
3
+examples

+ 18
- 0
node_modules/socket.io/node_modules/base64id/README.md View File

@@ -0,0 +1,18 @@
1
+base64id
2
+========
3
+
4
+Node.js module that generates a base64 id.
5
+
6
+Uses crypto.randomBytes when available, falls back to unsafe methods for node.js <= 0.4.
7
+
8
+To increase performance, random bytes are buffered to minimize the number of synchronous calls to crypto.randomBytes.
9
+
10
+## Installation
11
+
12
+   $ npm install mongoose
13
+
14
+## Usage
15
+
16
+   var base64id = require('base64id');
17
+
18
+   var id = base64id.generateId();

+ 103
- 0
node_modules/socket.io/node_modules/base64id/lib/base64id.js View File

@@ -0,0 +1,103 @@
1
+/*!
2
+ * base64id v0.1.0
3
+ */
4
+
5
+/**
6
+ * Module dependencies
7
+ */
8
+
9
+var crypto = require('crypto');
10
+
11
+/**
12
+ * Constructor
13
+ */
14
+
15
+var Base64Id = function() { };
16
+
17
+/**
18
+ * Get random bytes
19
+ *
20
+ * Uses a buffer if available, falls back to crypto.randomBytes
21
+ */
22
+
23
+Base64Id.prototype.getRandomBytes = function(bytes) {
24
+
25
+  var BUFFER_SIZE = 4096
26
+  var self = this;  
27
+  
28
+  bytes = bytes || 12;
29
+
30
+  if (bytes > BUFFER_SIZE) {
31
+    return crypto.randomBytes(bytes);
32
+  }
33
+  
34
+  var bytesInBuffer = parseInt(BUFFER_SIZE/bytes);
35
+  var threshold = parseInt(bytesInBuffer*0.85);
36
+
37
+  if (!threshold) {
38
+    return crypto.randomBytes(bytes);
39
+  }
40
+
41
+  if (this.bytesBufferIndex == null) {
42
+     this.bytesBufferIndex = -1;
43
+  }
44
+
45
+  if (this.bytesBufferIndex == bytesInBuffer) {
46
+    this.bytesBuffer = null;
47
+    this.bytesBufferIndex = -1;
48
+  }
49
+
50
+  // No buffered bytes available or index above threshold
51
+  if (this.bytesBufferIndex == -1 || this.bytesBufferIndex > threshold) {
52
+     
53
+    if (!this.isGeneratingBytes) {
54
+      this.isGeneratingBytes = true;
55
+      crypto.randomBytes(BUFFER_SIZE, function(err, bytes) {
56
+        self.bytesBuffer = bytes;
57
+        self.bytesBufferIndex = 0;
58
+        self.isGeneratingBytes = false;
59
+      }); 
60
+    }
61
+    
62
+    // Fall back to sync call when no buffered bytes are available
63
+    if (this.bytesBufferIndex == -1) {
64
+      return crypto.randomBytes(bytes);
65
+    }
66
+  }
67
+  
68
+  var result = this.bytesBuffer.slice(bytes*this.bytesBufferIndex, bytes*(this.bytesBufferIndex+1)); 
69
+  this.bytesBufferIndex++; 
70
+  
71
+  return result;
72
+}
73
+
74
+/**
75
+ * Generates a base64 id
76
+ *
77
+ * (Original version from socket.io <http://socket.io>)
78
+ */
79
+
80
+Base64Id.prototype.generateId = function () {
81
+  var rand = new Buffer(15); // multiple of 3 for base64
82
+  if (!rand.writeInt32BE) {
83
+    return Math.abs(Math.random() * Math.random() * Date.now() | 0).toString()
84
+      + Math.abs(Math.random() * Math.random() * Date.now() | 0).toString();
85
+  }
86
+  this.sequenceNumber = (this.sequenceNumber + 1) | 0;
87
+  rand.writeInt32BE(this.sequenceNumber, 11);
88
+  if (crypto.randomBytes) {
89
+    this.getRandomBytes(12).copy(rand);
90
+  } else {
91
+    // not secure for node 0.4
92
+    [0, 4, 8].forEach(function(i) {
93
+      rand.writeInt32BE(Math.random() * Math.pow(2, 32) | 0, i);
94
+    });
95
+  }
96
+  return rand.toString('base64').replace(/\//g, '_').replace(/\+/g, '-');
97
+};
98
+
99
+/**
100
+ * Export
101
+ */
102
+
103
+exports = module.exports = new Base64Id();

+ 29
- 0
node_modules/socket.io/node_modules/base64id/package.json View File

@@ -0,0 +1,29 @@
1
+{
2
+  "name": "base64id",
3
+  "version": "0.1.0",
4
+  "description": "Generates a base64 id",
5
+  "author": {
6
+    "name": "Kristian Faeldt",
7
+    "email": "faeldt_kristian@cyberagent.co.jp"
8
+  },
9
+  "repository": {
10
+    "type": "git",
11
+    "url": "git://github.com/faeldt/base64id.git"
12
+  },
13
+  "main": "./lib/base64id.js",
14
+  "engines": {
15
+    "node": ">= 0.4.0"
16
+  },
17
+  "_id": "base64id@0.1.0",
18
+  "dependencies": {},
19
+  "devDependencies": {},
20
+  "optionalDependencies": {},
21
+  "_engineSupported": true,
22
+  "_npmVersion": "1.1.4",
23
+  "_nodeVersion": "v0.6.19",
24
+  "_defaultsLoaded": true,
25
+  "dist": {
26
+    "shasum": "40e050cc1134533970d0be9d57467dc7494a4f27"
27
+  },
28
+  "_from": "base64id@0.1.0"
29
+}

+ 1
- 0
node_modules/socket.io/node_modules/policyfile/.npmignore View File

@@ -0,0 +1 @@
1
+node_modules

+ 19
- 0
node_modules/socket.io/node_modules/policyfile/LICENSE View File

@@ -0,0 +1,19 @@
1
+Copyright (c) 2011 Arnout Kazemier,3rd-Eden
2
+
3
+Permission is hereby granted, free of charge, to any person obtaining a copy
4
+of this software and associated documentation files (the "Software"), to deal
5
+in the Software without restriction, including without limitation the rights
6
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+copies of the Software, and to permit persons to whom the Software is
8
+furnished to do so, subject to the following conditions:
9
+
10
+The above copyright notice and this permission notice shall be included in
11
+all copies or substantial portions of the Software.
12
+
13
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+THE SOFTWARE.

+ 7
- 0
node_modules/socket.io/node_modules/policyfile/Makefile View File

@@ -0,0 +1,7 @@
1
+doc:
2
+	dox --title "FlashPolicyFileServer" lib/* > doc/index.html
3
+
4
+test:
5
+	expresso -I lib $(TESTFLAGS) tests/*.test.js
6
+
7
+.PHONY: test doc

+ 98
- 0
node_modules/socket.io/node_modules/policyfile/README.md View File

@@ -0,0 +1,98 @@
1
+## LOL, WUT?
2
+It basically allows you to allow or disallow Flash Player sockets from accessing your site.
3
+
4
+## Installation
5
+
6
+```bash
7
+npm install policyfile
8
+```
9
+## Usage
10
+
11
+The server is based on the regular and know `net` and `http` server patterns. So it you can just listen
12
+for all the events that a `net` based server emits etc. But there is one extra event, the `connect_failed`
13
+event. This event is triggered when we are unable to listen on the supplied port number.
14
+
15
+### createServer
16
+Creates a new server instance and accepts 2 optional arguments:
17
+
18
+-  `options` **Object** Options to configure the server instance
19
+    -  `log` **Boolean** Enable logging to STDOUT and STDERR (defaults to true)
20
+-  `origins` **Array** An Array of origins that are allowed by the server (defaults to *:*)
21
+
22
+```js
23
+var pf = require('policyfile');
24
+pf.createServer();
25
+pf.listen();
26
+```
27
+
28
+#### server.listen
29
+Start listening on the server and it takes 3 optional arguments
30
+
31
+-  `port` **Number** On which port number should we listen? (defaults to 843, which is the first port number the FlashPlayer checks)
32
+-  `server` **Server** A http server, if we are unable to accept requests or run the server we can also answer the policy requests inline over the supplied HTTP server.
33
+-  `callback` **Function** A callback function that is called when listening to the server was successful.
34
+
35
+```js
36
+var pf = require('policyfile');
37
+pf.createServer();
38
+pf.listen(1337, function(){
39
+  console.log(':3 yay')
40
+});
41
+```
42
+
43
+Changing port numbers can be handy if you do not want to run your server as root and have port 843 forward to a non root port number (aka a number above 1024).
44
+
45
+```js
46
+var pf = require('policyfile')
47
+  , http = require('http');
48
+
49
+server = http.createServer(function(q,r){r.writeHead(200);r.end('hello world')});
50
+server.listen(80);
51
+
52
+pf.createServer();
53
+pf.listen(1337, server, function(){
54
+  console.log(':3 yay')
55
+});
56
+```
57
+
58
+Support for serving inline requests over a existing HTTP connection as the FlashPlayer will first check port 843, but if it's unable to get a response there it will send a policy file request over port 80, which is usually your http server.
59
+
60
+#### server.add
61
+Adds more origins to the policy file you can add as many arguments as you like.
62
+
63
+```js
64
+var pf = require('policyfile');
65
+pf.createServer(['google.com:80']);
66
+pf.listen();
67
+pf.add('blog.3rd-Eden.com:80', 'blog.3rd-Eden.com:8080'); // now has 3 origins
68
+```
69
+
70
+#### server.add
71
+Adds more origins to the policy file you can add as many arguments as you like.
72
+
73
+```js
74
+var pf = require('policyfile');
75
+pf.createServer(['blog.3rd-Eden.com:80', 'blog.3rd-Eden.com:8080']);
76
+pf.listen();
77
+pf.remove('blog.3rd-Eden.com:8080'); // only contains the :80 version now
78
+```
79
+
80
+#### server.close
81
+Shuts down the server
82
+
83
+```js
84
+var pf = require('policyfile');
85
+pf.createServer();
86
+pf.listen();
87
+pf.close(); // OH NVM.
88
+```
89
+
90
+## API
91
+http://3rd-eden.com/FlashPolicyFileServer/
92
+
93
+## Examples
94
+See https://github.com/3rd-Eden/FlashPolicyFileServer/tree/master/examples for examples
95
+
96
+## Licence
97
+
98
+MIT see LICENSE file in the repository

+ 375
- 0
node_modules/socket.io/node_modules/policyfile/doc/index.html View File

@@ -0,0 +1,375 @@
1
+<html>
2
+	<head>
3
+		<title>FlashPolicyFileServer</title>
4
+		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
5
+		<style>body {
6
+    margin: 0;
7
+    padding: 0;
8
+    font: 14px/1.5 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
9
+    color: #252519;
10
+}
11
+a {
12
+    color: #252519;
13
+}
14
+a:hover {
15
+    text-decoration: underline;
16
+    color: #19469D;
17
+}
18
+p {
19
+    margin: 12px 0;
20
+}
21
+h1, h2, h3 {
22
+    margin: 0;
23
+    padding: 0;
24
+}
25
+table#source {
26
+    width: 100%;
27
+    border-collapse: collapse;
28
+}
29
+table#source td:first-child {
30
+    padding: 30px 40px 30px 40px;
31
+    vertical-align: top;
32
+}
33
+table#source td:first-child,
34
+table#source td:first-child pre {
35
+    width: 450px;
36
+}
37
+table#source td:last-child {
38
+    padding: 30px 0 30px 40px;
39
+    border-left: 1px solid #E5E5EE;
40
+    background: #F5F5FF;
41
+}
42
+table#source tr {
43
+    border-bottom: 1px solid #E5E5EE;
44
+}
45
+table#source tr.filename {
46
+    padding-top: 40px;
47
+    border-top: 1px solid #E5E5EE;
48
+}
49
+table#source tr.filename td:first-child {
50
+    text-transform: capitalize;
51
+}
52
+table#source tr.filename td:last-child {
53
+    font-size: 12px;
54
+}
55
+table#source tr.filename h2 {
56
+    margin: 0;
57
+    padding: 0;
58
+    cursor: pointer;
59
+}
60
+table#source tr.code h1,
61
+table#source tr.code h2,
62
+table#source tr.code h3 {
63
+    margin-top: 30px;
64
+    font-family: "Lucida Grande", "Helvetica Nueue", Arial, sans-serif;
65
+    font-size: 18px;
66
+}
67
+table#source tr.code h2 {
68
+    font-size: 16px;
69
+}
70
+table#source tr.code h3 {
71
+    font-size: 14px;
72
+}
73
+table#source tr.code ul {
74
+    margin: 15px 0 15px 35px;
75
+    padding: 0;
76
+}
77
+table#source tr.code ul li {
78
+    margin: 0;
79
+    padding: 1px 0;
80
+}
81
+table#source tr.code ul li p {
82
+    margin: 0;
83
+    padding: 0;
84
+}
85
+table#source tr.code td:first-child pre {
86
+    padding: 20px;
87
+}
88
+#ribbon {
89
+    position: fixed;
90
+    top: 0;
91
+    right: 0;
92
+}
93
+code .string { color: #219161; }
94
+code .regexp { color: #219161; }
95
+code .keyword { color: #954121; }
96
+code .number { color: #19469D; }
97
+code .comment { color: #bbb; }
98
+code .this { color: #19469D; }</style>
99
+		<script>
100
+			$(function(){
101
+				$('tr.code').hide();
102
+				$('tr.filename').toggle(function(){
103
+					$(this).nextUntil('.filename').fadeIn();
104
+				}, function(){
105
+					$(this).nextUntil('.filename').fadeOut();
106
+				});
107
+			});
108
+		</script>
109
+	</head>
110
+	<body>
111
+<table id="source"><tbody><tr><td><h1>FlashPolicyFileServer</h1></td><td></td></tr><tr class="filename"><td><h2 id="lib/server.js"><a href="#">server</a></h2></td><td>lib/server.js</td></tr><tr class="code">
112
+<td class="docs">
113
+<p>Module dependencies and cached references.
114
+ </p>
115
+</td>
116
+<td class="code">
117
+<pre><code><span class="keyword">var</span> <span class="variable">slice</span> = <span class="class">Array</span>.<span class="variable">prototype</span>.<span class="variable">slice</span>
118
+  , <span class="variable">net</span> = <span class="variable">require</span>(<span class="string">'net'</span>);</code></pre>
119
+</td>
120
+</tr>
121
+<tr class="code">
122
+<td class="docs">
123
+<p>The server that does the Policy File severing</p>
124
+
125
+<h2>Options</h2>
126
+
127
+<ul><li><code>log</code>  false or a function that can output log information, defaults to console.log?</li></ul>
128
+
129
+<h2></h2>
130
+
131
+<ul><li><p><strong>param</strong>: <em>Object</em>  options Options to customize the servers functionality.</p></li><li><p><strong>param</strong>: <em>Array</em>  origins The origins that are allowed on this server, defaults to <code>*:*</code>.</p></li><li><p><strong>api</strong>: <em>public</em></p></li></ul>
132
+</td>
133
+<td class="code">
134
+<pre><code><span class="keyword">function</span> <span class="class">Server</span>(<span class="variable">options</span>, <span class="variable">origins</span>){
135
+  <span class="keyword">var</span> <span class="variable">me</span> = <span class="this">this</span>;
136
+  
137
+  <span class="this">this</span>.<span class="variable">origins</span> = <span class="variable">origins</span> || [<span class="string">'*:*'</span>];
138
+  <span class="this">this</span>.<span class="variable">port</span> = <span class="number integer">843</span>;
139
+  <span class="this">this</span>.<span class="variable">log</span> = <span class="variable">console</span>.<span class="variable">log</span>;
140
+  
141
+  <span class="comment">// merge `this` with the options</span>
142
+  <span class="class">Object</span>.<span class="variable">keys</span>(<span class="variable">options</span>).<span class="variable">forEach</span>(<span class="keyword">function</span>(<span class="variable">key</span>){
143
+    <span class="variable">me</span>[<span class="variable">key</span>] &<span class="variable">amp</span>;&<span class="variable">amp</span>; (<span class="variable">me</span>[<span class="variable">key</span>] = <span class="variable">options</span>[<span class="variable">key</span>])
144
+  });
145
+  
146
+  <span class="comment">// create the net server</span>
147
+  <span class="this">this</span>.<span class="variable">socket</span> = <span class="variable">net</span>.<span class="variable">createServer</span>(<span class="keyword">function</span> <span class="variable">createServer</span>(<span class="variable">socket</span>){
148
+    <span class="variable">socket</span>.<span class="variable">on</span>(<span class="string">'error'</span>, <span class="keyword">function</span> <span class="variable">socketError</span>(){ <span class="variable">me</span>.<span class="variable">responder</span>.<span class="variable">call</span>(<span class="variable">me</span>, <span class="variable">socket</span>) });
149
+    <span class="variable">me</span>.<span class="variable">responder</span>.<span class="variable">call</span>(<span class="variable">me</span>, <span class="variable">socket</span>);
150
+  });
151
+  
152
+  <span class="comment">// Listen for errors as the port might be blocked because we do not have root priv.</span>
153
+  <span class="this">this</span>.<span class="variable">socket</span>.<span class="variable">on</span>(<span class="string">'error'</span>, <span class="keyword">function</span> <span class="variable">serverError</span>(<span class="variable">err</span>){
154
+    <span class="comment">// Special and common case error handling</span>
155
+    <span class="keyword">if</span> (<span class="variable">err</span>.<span class="variable">errno</span> == <span class="number integer">13</span>){
156
+      <span class="variable">me</span>.<span class="variable">log</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">me</span>.<span class="variable">log</span>(
157
+        <span class="string">'Unable to listen to port `'</span> + <span class="variable">me</span>.<span class="variable">port</span> + <span class="string">'` as your Node.js instance does not have root privileges. '</span> +
158
+        (
159
+          <span class="variable">me</span>.<span class="variable">server</span>
160
+          ? <span class="string">'The Flash Policy file will now be served inline over the supplied HTTP server, Flash Policy files request will suffer.'</span>
161
+          : <span class="string">'No fallback server supplied.'</span>
162
+        )
163
+      );
164
+      
165
+      <span class="variable">me</span>.<span class="variable">socket</span>.<span class="variable">removeAllListeners</span>();
166
+      <span class="keyword">delete</span> <span class="variable">me</span>.<span class="variable">socket</span>;
167
+
168
+      <span class="variable">me</span>.<span class="variable">emit</span>(<span class="string">'connect_failed'</span>, <span class="variable">err</span>);
169
+    } <span class="keyword">else</span> {
170
+      <span class="variable">me</span>.<span class="variable">log</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">me</span>.<span class="variable">log</span>(<span class="string">'FlashPolicyFileServer received a error event:\n'</span> + (<span class="variable">err</span>.<span class="variable">message</span> ? <span class="variable">err</span>.<span class="variable">message</span> : <span class="variable">err</span>));
171
+    }
172
+  });
173
+  
174
+  <span class="this">this</span>.<span class="variable">socket</span>.<span class="variable">on</span>(<span class="string">'timeout'</span>, <span class="keyword">function</span> <span class="variable">serverTimeout</span>(){});
175
+  <span class="this">this</span>.<span class="variable">socket</span>.<span class="variable">on</span>(<span class="string">'close'</span>, <span class="keyword">function</span> <span class="variable">serverClosed</span>(<span class="variable">err</span>){
176
+    <span class="variable">err</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">me</span>.<span class="variable">log</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">me</span>.<span class="variable">log</span>(<span class="string">'Server closing due to an error: \n'</span> + (<span class="variable">err</span>.<span class="variable">message</span> ? <span class="variable">err</span>.<span class="variable">message</span> : <span class="variable">err</span>));
177
+    
178
+    <span class="keyword">if</span> (<span class="variable">me</span>.<span class="variable">server</span>){
179
+      <span class="comment">// not online anymore</span>
180
+      <span class="keyword">delete</span> <span class="variable">me</span>.<span class="variable">server</span>.<span class="variable">online</span>;
181
+      
182
+      <span class="comment">// Remove the inline policy listener if we close down</span>
183
+      <span class="comment">// but only when the server was `online` (see listen prototype)</span>
184
+      <span class="keyword">if</span>( <span class="variable">me</span>.<span class="variable">server</span>[<span class="string">'@'</span>] &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">me</span>.<span class="variable">server</span>.<span class="variable">online</span>){
185
+        <span class="variable">me</span>.<span class="variable">server</span>.<span class="variable">removeListener</span>(<span class="string">'connection'</span>, <span class="variable">me</span>.<span class="variable">server</span>[<span class="string">'@'</span>]);
186
+      }
187
+    }
188
+    <span class="variable">me</span>.<span class="variable">log</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">me</span>.<span class="variable">log</span>(<span class="string">'Shutting down FlashPolicyFileServer'</span>);
189
+  });
190
+  
191
+  <span class="comment">// Compile the initial `buffer`</span>
192
+  <span class="this">this</span>.<span class="variable">compile</span>();
193
+}</code></pre>
194
+</td>
195
+</tr>
196
+<tr class="code">
197
+<td class="docs">
198
+<p>Start listening for requests</p>
199
+
200
+<h2></h2>
201
+
202
+<ul><li><p><strong>param</strong>: <em>Number</em>  port The port number it should be listening to.</p></li><li><p><strong>param</strong>: <em>Server</em>  server A HTTP server instance, this will be used to listen for inline requests</p></li><li><p><strong>param</strong>: <em>Function</em>  cb The callback needs to be called once server is ready</p></li><li><p><strong>api</strong>: <em>public</em></p></li></ul>
203
+</td>
204
+<td class="code">
205
+<pre><code><span class="class">Server</span>.<span class="variable">prototype</span>.<span class="variable">listen</span> = <span class="keyword">function</span> <span class="variable">listen</span>(<span class="variable">port</span>, <span class="variable">server</span>, <span class="variable">cb</span>){
206
+  <span class="keyword">var</span> <span class="variable">me</span> = <span class="this">this</span>
207
+    , <span class="variable">args</span> = <span class="variable">slice</span>.<span class="variable">call</span>(<span class="variable">arguments</span>, <span class="number integer">0</span>)
208
+    , <span class="variable">callback</span>;
209
+  
210
+  <span class="comment">// assign the correct vars, for flexible arguments</span>
211
+  <span class="variable">args</span>.<span class="variable">forEach</span>(<span class="keyword">function</span> <span class="variable">args</span>(<span class="variable">arg</span>){
212
+    <span class="keyword">var</span> <span class="variable">type</span> = <span class="keyword">typeof</span> <span class="variable">arg</span>;
213
+    
214
+    <span class="keyword">if</span> (<span class="variable">type</span> === <span class="string">'number'</span>) <span class="variable">me</span>.<span class="variable">port</span> = <span class="variable">arg</span>;
215
+    <span class="keyword">if</span> (<span class="variable">type</span> === <span class="string">'function'</span>) <span class="variable">callback</span> = <span class="variable">arg</span>;
216
+    <span class="keyword">if</span> (<span class="variable">type</span> === <span class="string">'object'</span>) <span class="variable">me</span>.<span class="variable">server</span> = <span class="variable">arg</span>;
217
+  });
218
+  
219
+  <span class="keyword">if</span> (<span class="this">this</span>.<span class="variable">server</span>){
220
+    
221
+    <span class="comment">// no one in their right mind would ever create a `@` prototype, so Im just gonna store</span>
222
+    <span class="comment">// my function on the server, so I can remove it later again once the server(s) closes</span>
223
+    <span class="this">this</span>.<span class="variable">server</span>[<span class="string">'@'</span>] = <span class="keyword">function</span> <span class="variable">connection</span>(<span class="variable">socket</span>){
224
+      <span class="variable">socket</span>.<span class="variable">once</span>(<span class="string">'data'</span>, <span class="keyword">function</span> <span class="variable">requestData</span>(<span class="variable">data</span>){
225
+        <span class="comment">// if it's a Flash policy request, and we can write to the </span>
226
+        <span class="keyword">if</span> (
227
+             <span class="variable">data</span>
228
+          &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">data</span>[<span class="number integer">0</span>] === <span class="number integer">60</span>
229
+          &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">data</span>.<span class="variable">toString</span>() === <span class="string">'&lt;policy-file-request/&gt;\0'</span>
230
+          &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">socket</span>
231
+          &<span class="variable">amp</span>;&<span class="variable">amp</span>; (<span class="variable">socket</span>.<span class="variable">readyState</span> === <span class="string">'open'</span> || <span class="variable">socket</span>.<span class="variable">readyState</span> === <span class="string">'writeOnly'</span>)
232
+        ){
233
+          <span class="comment">// send the buffer</span>
234
+          <span class="variable">socket</span>.<span class="variable">end</span>(<span class="variable">me</span>.<span class="variable">buffer</span>);
235
+        }
236
+      });
237
+    };
238
+    <span class="comment">// attach it</span>
239
+    <span class="this">this</span>.<span class="variable">server</span>.<span class="variable">on</span>(<span class="string">'connection'</span>, <span class="this">this</span>.<span class="variable">server</span>[<span class="string">'@'</span>]);
240
+  }
241
+  
242
+  <span class="comment">// We add a callback method, so we can set a flag for when the server is `enabled` or `online`.</span>
243
+  <span class="comment">// this flag is needed because if a error occurs and the we cannot boot up the server the</span>
244
+  <span class="comment">// fallback functionality should not be removed during the `close` event</span>
245
+  <span class="this">this</span>.<span class="variable">socket</span>.<span class="variable">listen</span>(<span class="this">this</span>.<span class="variable">port</span>, <span class="keyword">function</span> <span class="variable">serverListening</span>(){
246
+   <span class="variable">me</span>.<span class="variable">socket</span>.<span class="variable">online</span> = <span class="variable">true</span>;
247
+   
248
+   <span class="keyword">if</span> (<span class="variable">callback</span>) <span class="variable">callback</span>(), <span class="variable">callback</span> = <span class="variable">undefined</span>;
249
+   
250
+  });
251
+  
252
+  <span class="keyword">return</span> <span class="this">this</span>;
253
+};</code></pre>
254
+</td>
255
+</tr>
256
+<tr class="code">
257
+<td class="docs">
258
+<p>Adds a new origin to the Flash Policy File.</p>
259
+
260
+<h2></h2>
261
+
262
+<ul><li><p><strong>param</strong>: <em>Arguments</em>  The origins that need to be added.</p></li><li><p><strong>api</strong>: <em>public</em></p></li></ul>
263
+</td>
264
+<td class="code">
265
+<pre><code><span class="class">Server</span>.<span class="variable">prototype</span>.<span class="variable">add</span> = <span class="keyword">function</span> <span class="variable">add</span>(){
266
+  <span class="keyword">var</span> <span class="variable">args</span> = <span class="variable">slice</span>.<span class="variable">call</span>(<span class="variable">arguments</span>, <span class="number integer">0</span>)
267
+    , <span class="variable">i</span> = <span class="variable">args</span>.<span class="variable">length</span>;
268
+  
269
+  <span class="comment">// flag duplicates</span>
270
+  <span class="keyword">while</span> (<span class="variable">i</span>--){
271
+    <span class="keyword">if</span> (<span class="this">this</span>.<span class="variable">origins</span>.<span class="variable">indexOf</span>(<span class="variable">args</span>[<span class="variable">i</span>]) &<span class="variable">gt</span>;= <span class="number integer">0</span>){
272
+      <span class="variable">args</span>[<span class="variable">i</span>] = <span class="keyword">null</span>;
273
+    }
274
+  }
275
+  
276
+  <span class="comment">// Add all the arguments to the array</span>
277
+  <span class="comment">// but first we want to remove all `falsy` values from the args</span>
278
+  <span class="class">Array</span>.<span class="variable">prototype</span>.<span class="variable">push</span>.<span class="variable">apply</span>(
279
+    <span class="this">this</span>.<span class="variable">origins</span>
280
+  , <span class="variable">args</span>.<span class="variable">filter</span>(<span class="keyword">function</span>(<span class="variable">value</span>){ <span class="keyword">return</span> !!<span class="variable">value</span> })
281
+  );
282
+  
283
+  <span class="this">this</span>.<span class="variable">compile</span>();
284
+  <span class="keyword">return</span> <span class="this">this</span>;
285
+};</code></pre>
286
+</td>
287
+</tr>
288
+<tr class="code">
289
+<td class="docs">
290
+<p>Removes a origin from the Flash Policy File.</p>
291
+
292
+<h2></h2>
293
+
294
+<ul><li><p><strong>param</strong>: <em>String</em>  origin The origin that needs to be removed from the server</p></li><li><p><strong>api</strong>: <em>public</em></p></li></ul>
295
+</td>
296
+<td class="code">
297
+<pre><code><span class="class">Server</span>.<span class="variable">prototype</span>.<span class="variable">remove</span> = <span class="keyword">function</span> <span class="variable">remove</span>(<span class="variable">origin</span>){
298
+  <span class="keyword">var</span> <span class="variable">position</span> = <span class="this">this</span>.<span class="variable">origins</span>.<span class="variable">indexOf</span>(<span class="variable">origin</span>);
299
+  
300
+  <span class="comment">// only remove and recompile if we have a match</span>
301
+  <span class="keyword">if</span> (<span class="variable">position</span> &<span class="variable">gt</span>; <span class="number integer">0</span>){
302
+    <span class="this">this</span>.<span class="variable">origins</span>.<span class="variable">splice</span>(<span class="variable">position</span>,<span class="number integer">1</span>);
303
+    <span class="this">this</span>.<span class="variable">compile</span>();
304
+  }
305
+  
306
+  <span class="keyword">return</span> <span class="this">this</span>;
307
+};</code></pre>
308
+</td>
309
+</tr>
310
+<tr class="code">
311
+<td class="docs">
312
+<p>Closes and cleans up the server</p>
313
+
314
+<ul><li><p><strong>api</strong>: <em>public</em></p></li></ul>
315
+</td>
316
+<td class="code">
317
+<pre><code><span class="class">Server</span>.<span class="variable">prototype</span>.<span class="variable">close</span> = <span class="keyword">function</span> <span class="variable">close</span>(){
318
+  <span class="this">this</span>.<span class="variable">socket</span>.<span class="variable">removeAllListeners</span>();
319
+  <span class="this">this</span>.<span class="variable">socket</span>.<span class="variable">close</span>();
320
+  
321
+  <span class="keyword">return</span> <span class="this">this</span>;
322
+};</code></pre>
323
+</td>
324
+</tr>
325
+<tr class="code">
326
+<td class="docs">
327
+<p>Proxy the event listener requests to the created Net server
328
+ </p>
329
+</td>
330
+<td class="code">
331
+<pre><code><span class="class">Object</span>.<span class="variable">keys</span>(<span class="variable">process</span>.<span class="class">EventEmitter</span>.<span class="variable">prototype</span>).<span class="variable">forEach</span>(<span class="keyword">function</span> <span class="variable">proxy</span>(<span class="variable">key</span>){
332
+  <span class="class">Server</span>.<span class="variable">prototype</span>[<span class="variable">key</span>] = <span class="class">Server</span>.<span class="variable">prototype</span>[<span class="variable">key</span>] || <span class="keyword">function</span> (){
333
+    <span class="keyword">if</span> (<span class="this">this</span>.<span class="variable">socket</span>) <span class="this">this</span>.<span class="variable">socket</span>[<span class="variable">key</span>].<span class="variable">apply</span>(<span class="this">this</span>.<span class="variable">socket</span>, <span class="variable">arguments</span>);
334
+    <span class="keyword">return</span> <span class="this">this</span>;
335
+  };
336
+});</code></pre>
337
+</td>
338
+</tr>
339
+<tr class="code">
340
+<td class="docs">
341
+<p>Creates a new server instance.</p>
342
+
343
+<h2></h2>
344
+
345
+<ul><li><p><strong>param</strong>: <em>Object</em>  options A options object to override the default config</p></li><li><p><strong>param</strong>: <em>Array</em>  origins The origins that should be allowed by the server</p></li><li><p><strong>api</strong>: <em>public</em></p></li></ul>
346
+</td>
347
+<td class="code">
348
+<pre><code><span class="variable">exports</span>.<span class="variable">createServer</span> = <span class="keyword">function</span> <span class="variable">createServer</span>(<span class="variable">options</span>, <span class="variable">origins</span>){
349
+  <span class="variable">origins</span> = <span class="class">Array</span>.<span class="variable">isArray</span>(<span class="variable">origins</span>) ? <span class="variable">origins</span> : (<span class="class">Array</span>.<span class="variable">isArray</span>(<span class="variable">options</span>) ? <span class="variable">options</span> : <span class="variable">false</span>);
350
+  <span class="variable">options</span> = !<span class="class">Array</span>.<span class="variable">isArray</span>(<span class="variable">options</span>) &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">options</span> ? <span class="variable">options</span> : {};
351
+  
352
+  <span class="keyword">return</span> <span class="keyword">new</span> <span class="class">Server</span>(<span class="variable">options</span>, <span class="variable">origins</span>);
353
+};</code></pre>
354
+</td>
355
+</tr>
356
+<tr class="code">
357
+<td class="docs">
358
+<p>Provide a hook to the original server, so it can be extended if needed.
359
+ </p>
360
+</td>
361
+<td class="code">
362
+<pre><code><span class="variable">exports</span>.<span class="class">Server</span> = <span class="class">Server</span>;</code></pre>
363
+</td>
364
+</tr>
365
+<tr class="code">
366
+<td class="docs">
367
+<p>Module version
368
+ </p>
369
+</td>
370
+<td class="code">
371
+<pre><code><span class="variable">exports</span>.<span class="variable">version</span> = <span class="string">'0.0.2'</span>;
372
+</code></pre>
373
+</td>
374
+</tr>	</body>
375
+</html></tbody></table>

+ 8
- 0
node_modules/socket.io/node_modules/policyfile/examples/basic.fallback.js View File

@@ -0,0 +1,8 @@
1
+var http = require('http')
2
+  , fspfs = require('../');
3
+
4
+var server = http.createServer(function(q,r){ r.writeHead(200); r.end(':3') }) 
5
+  , flash = fspfs.createServer();
6
+
7
+server.listen(8080);
8
+flash.listen(8081,server);

+ 5
- 0
node_modules/socket.io/node_modules/policyfile/examples/basic.js View File

@@ -0,0 +1,5 @@
1
+var http = require('http')
2
+  , fspfs = require('../');
3
+
4
+var flash = fspfs.createServer();
5
+flash.listen();

+ 1
- 0
node_modules/socket.io/node_modules/policyfile/index.js View File

@@ -0,0 +1 @@
1
+module.exports = require('./lib/server.js');

+ 289
- 0
node_modules/socket.io/node_modules/policyfile/lib/server.js View File

@@ -0,0 +1,289 @@
1
+/**
2
+ * Module dependencies and cached references.
3
+ */
4
+
5
+var slice = Array.prototype.slice
6
+  , net = require('net');
7
+
8
+/**
9
+ * The server that does the Policy File severing
10
+ *
11
+ * Options:
12
+ *   - `log`  false or a function that can output log information, defaults to console.log?
13
+ *
14
+ * @param {Object} options Options to customize the servers functionality.
15
+ * @param {Array} origins The origins that are allowed on this server, defaults to `*:*`.
16
+ * @api public
17
+ */
18
+
19
+function Server (options, origins) {
20
+  var me = this;
21
+
22
+  this.origins = origins || ['*:*'];
23
+  this.port = 843;
24
+  this.log = console.log;
25
+
26
+  // merge `this` with the options
27
+  Object.keys(options).forEach(function (key) {
28
+    me[key] && (me[key] = options[key])
29
+  });
30
+
31
+  // create the net server
32
+  this.socket = net.createServer(function createServer (socket) {
33
+    socket.on('error', function socketError () { 
34
+      me.responder.call(me, socket);
35
+    });
36
+
37
+    me.responder.call(me, socket);
38
+  });
39
+
40
+  // Listen for errors as the port might be blocked because we do not have root priv.
41
+  this.socket.on('error', function serverError (err) {
42
+    // Special and common case error handling
43
+    if (err.errno == 13) {
44
+      me.log && me.log(
45
+        'Unable to listen to port `' + me.port + '` as your Node.js instance does not have root privileges. ' +
46
+        (
47
+          me.server
48
+          ? 'The Flash Policy File requests will only be served inline over the supplied HTTP server. Inline serving is slower than a dedicated server instance.'
49
+          : 'No fallback server supplied, we will be unable to answer Flash Policy File requests.'
50
+        )
51
+      );
52
+
53
+      me.emit('connect_failed', err);
54
+      me.socket.removeAllListeners();
55
+      delete me.socket;
56
+    } else {
57
+      me.log && me.log('FlashPolicyFileServer received an error event:\n' + (err.message ? err.message : err));
58
+    }
59
+  });
60
+
61
+  this.socket.on('timeout', function serverTimeout () {});
62
+  this.socket.on('close', function serverClosed (err) {
63
+    err && me.log && me.log('Server closing due to an error: \n' + (err.message ? err.message : err));
64
+
65
+    if (me.server) {
66
+      // Remove the inline policy listener if we close down
67
+      // but only when the server was `online` (see listen prototype)
68
+      if (me.server['@'] && me.server.online) {
69
+        me.server.removeListener('connection', me.server['@']);
70
+      }
71
+
72
+      // not online anymore
73
+      delete me.server.online;
74
+    }
75
+  });
76
+
77
+  // Compile the initial `buffer`
78
+  this.compile();
79
+}
80
+
81
+/**
82
+ * Start listening for requests
83
+ *
84
+ * @param {Number} port The port number it should be listening to.
85
+ * @param {Server} server A HTTP server instance, this will be used to listen for inline requests
86
+ * @param {Function} cb The callback needs to be called once server is ready
87
+ * @api public
88
+ */
89
+
90
+Server.prototype.listen = function listen (port, server, cb){
91
+  var me = this
92
+    , args = slice.call(arguments, 0)
93
+    , callback;
94
+ 
95
+  // assign the correct vars, for flexible arguments
96
+  args.forEach(function args (arg){
97
+    var type = typeof arg;
98
+
99
+    if (type === 'number') me.port = arg;
100
+    if (type === 'function') callback = arg;
101
+    if (type === 'object') me.server = arg;
102
+  });
103
+
104
+  if (this.server) {
105
+
106
+    // no one in their right mind would ever create a `@` prototype, so Im just gonna store
107
+    // my function on the server, so I can remove it later again once the server(s) closes
108
+    this.server['@'] = function connection (socket) {
109
+      socket.once('data', function requestData (data) {
110
+        // if it's a Flash policy request, and we can write to the 
111
+        if (
112
+             data
113
+          && data[0] === 60
114
+          && data.toString() === '<policy-file-request/>\0'
115
+          && socket
116
+          && (socket.readyState === 'open' || socket.readyState === 'writeOnly')
117
+        ){
118
+          // send the buffer
119
+          try {
120
+            socket.end(me.buffer);
121
+          } catch (e) {}
122
+        }
123
+      });
124
+    };
125
+
126
+    // attach it
127
+    this.server.on('connection', this.server['@']);
128
+  }
129
+
130
+  // We add a callback method, so we can set a flag for when the server is `enabled` or `online`.
131
+  // this flag is needed because if a error occurs and the we cannot boot up the server the
132
+  // fallback functionality should not be removed during the `close` event
133
+  this.port >= 0 && this.socket.listen(this.port, function serverListening () {
134
+    me.socket.online = true;
135
+    if (callback) {
136
+      callback.call(me);
137
+      callback = undefined;
138
+    }
139
+  });
140
+
141
+  return this;
142
+};
143
+
144
+/**
145
+ * Responds to socket connects and writes the compile policy file.
146
+ *
147
+ * @param {net.Socket} socket The socket that needs to receive the message
148
+ * @api private
149
+ */
150
+
151
+Server.prototype.responder = function responder (socket){
152
+  if (socket && socket.readyState == 'open' && socket.end) {
153
+    try {
154
+      socket.end(this.buffer);
155
+    } catch (e) {}
156
+  }
157
+};
158
+
159
+/**
160
+ * Compiles the supplied origins to a Flash Policy File format and stores it in a Node.js Buffer
161
+ * this way it can be send over the wire without any performance loss.
162
+ *
163
+ * @api private
164
+ */
165
+
166
+Server.prototype.compile = function compile (){
167
+  var xml = [
168
+        '<?xml version="1.0"?>'
169
+      , '<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">'
170
+      , '<cross-domain-policy>'
171
+    ];
172
+
173
+  // add the allow access element
174
+  this.origins.forEach(function origin (origin){
175
+    var parts = origin.split(':');
176
+    xml.push('<allow-access-from domain="' + parts[0] + '" to-ports="'+ parts[1] +'"/>');
177
+  });
178
+
179
+  xml.push('</cross-domain-policy>');
180
+
181
+  // store the result in a buffer so we don't have to re-generate it all the time
182
+  this.buffer = new Buffer(xml.join(''), 'utf8');
183
+
184
+  return this;
185
+};
186
+
187
+/**
188
+ * Adds a new origin to the Flash Policy File.
189
+ *
190
+ * @param {Arguments} The origins that need to be added.
191
+ * @api public
192
+ */
193
+
194
+Server.prototype.add = function add(){
195
+  var args = slice.call(arguments, 0)
196
+    , i = args.length;
197
+
198
+  // flag duplicates
199
+  while (i--) {
200
+    if (this.origins.indexOf(args[i]) >= 0){
201
+      args[i] = null;
202
+    }
203
+  }
204
+
205
+  // Add all the arguments to the array
206
+  // but first we want to remove all `falsy` values from the args
207
+  Array.prototype.push.apply(
208
+    this.origins
209
+  , args.filter(function filter (value) {
210
+      return !!value;
211
+    })
212
+  );
213
+
214
+  this.compile();
215
+  return this;
216
+};
217
+
218
+/**
219
+ * Removes a origin from the Flash Policy File.
220
+ *
221
+ * @param {String} origin The origin that needs to be removed from the server
222
+ * @api public
223
+ */
224
+
225
+Server.prototype.remove = function remove (origin){
226
+  var position = this.origins.indexOf(origin);
227
+
228
+  // only remove and recompile if we have a match
229
+  if (position > 0) {
230
+    this.origins.splice(position,1);
231
+    this.compile();
232
+  }
233
+
234
+  return this;
235
+};
236
+
237
+/**
238
+ * Closes and cleans up the server
239
+ *
240
+ * @api public
241
+ */
242
+
243
+Server.prototype.close = function close () {
244
+  this.socket.removeAllListeners();
245
+  this.socket.close();
246
+
247
+  return this;
248
+};
249
+
250
+/**
251
+ * Proxy the event listener requests to the created Net server
252
+ */
253
+
254
+Object.keys(process.EventEmitter.prototype).forEach(function proxy (key){
255
+  Server.prototype[key] = Server.prototype[key] || function () {
256
+    if (this.socket) {
257
+      this.socket[key].apply(this.socket, arguments);
258
+    }
259
+
260
+    return this;
261
+  };
262
+});
263
+
264
+/**
265
+ * Creates a new server instance.
266
+ *
267
+ * @param {Object} options A options object to override the default config
268
+ * @param {Array} origins The origins that should be allowed by the server
269
+ * @api public
270
+ */
271
+
272
+exports.createServer = function createServer(options, origins){
273
+  origins = Array.isArray(origins) ? origins : (Array.isArray(options) ? options : false);
274
+  options = !Array.isArray(options) && options ? options : {};
275
+
276
+  return new Server(options, origins);
277
+};
278
+
279
+/**
280
+ * Provide a hook to the original server, so it can be extended if needed.
281
+ */
282
+
283
+exports.Server = Server;
284
+
285
+/**
286
+ * Module version
287
+ */
288
+
289
+exports.version = '0.0.4';

+ 55
- 0
node_modules/socket.io/node_modules/policyfile/package.json View File

@@ -0,0 +1,55 @@
1
+{
2
+  "name": "policyfile",
3
+  "version": "0.0.4",
4
+  "author": {
5
+    "name": "Arnout Kazemier"
6
+  },
7
+  "description": "Flash Socket Policy File Server. A server to respond to Flash Socket Policy requests, both inline and through a dedicated server instance.",
8
+  "main": "index",
9
+  "keywords": [
10
+    "flash",
11
+    "socket",
12
+    "policy",
13
+    "file",
14
+    "server",
15
+    "Flash Socket Policy File Server",
16
+    "cross domain"
17
+  ],
18
+  "directories": {
19
+    "lib": "./lib"
20
+  },
21
+  "maintainers": [
22
+    {
23
+      "name": "Arnout Kazemier",
24
+      "email": "info@3rd-Eden.com",
25
+      "url": "http://blog.3rd-Eden.com"
26
+    }
27
+  ],
28
+  "licenses": [
29
+    {
30
+      "type": "MIT",
31
+      "url": "https://github.com/3rd-Eden/FlashPolicyFileServer/blob/master/LICENSE"
32
+    }
33
+  ],
34
+  "repositories": [
35
+    {
36
+      "type": "git",
37
+      "url": "https://github.com/3rd-Eden/FlashPolicyFileServer.git"
38
+    }
39
+  ],
40
+  "_id": "policyfile@0.0.4",
41
+  "dependencies": {},
42
+  "devDependencies": {},
43
+  "optionalDependencies": {},
44
+  "engines": {
45
+    "node": "*"
46
+  },
47
+  "_engineSupported": true,
48
+  "_npmVersion": "1.1.4",
49
+  "_nodeVersion": "v0.6.19",
50
+  "_defaultsLoaded": true,
51
+  "dist": {
52
+    "shasum": "25f5196fbc0f8b3a59b0b10fd71c940a50f9a6a0"
53
+  },
54
+  "_from": "policyfile@0.0.4"
55
+}

+ 21
- 0
node_modules/socket.io/node_modules/policyfile/tests/ssl/ssl.crt View File

@@ -0,0 +1,21 @@
1
+-----BEGIN CERTIFICATE-----
2
+MIIDXTCCAkWgAwIBAgIJAMUSOvlaeyQHMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
3
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
4
+aWRnaXRzIFB0eSBMdGQwHhcNMTAxMTE2MDkzMjQ5WhcNMTMxMTE1MDkzMjQ5WjBF
5
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
6
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
7
+CgKCAQEAz+LXZOjcQCJq3+ZKUFabj71oo/ex/XsBcFqtBThjjTw9CVEVwfPQQp4X
8
+wtPiB204vnYXwQ1/R2NdTQqCZu47l79LssL/u2a5Y9+0NEU3nQA5qdt+1FAE0c5o
9
+exPimXOrR3GWfKz7PmZ2O0117IeCUUXPG5U8umhDe/4mDF4ZNJiKc404WthquTqg
10
+S7rLQZHhZ6D0EnGnOkzlmxJMYPNHSOY1/6ivdNUUcC87awNEA3lgfhy25IyBK3QJ
11
+c+aYKNTbt70Lery3bu2wWLFGtmNiGlQTS4JsxImRsECTI727ObS7/FWAQsqW+COL
12
+0Sa5BuMFrFIpjPrEe0ih7vRRbdmXRwIDAQABo1AwTjAdBgNVHQ4EFgQUDnV4d6mD
13
+tOnluLoCjkUHTX/n4agwHwYDVR0jBBgwFoAUDnV4d6mDtOnluLoCjkUHTX/n4agw
14
+DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAFwV4MQfTo+qMv9JMiyno
15
+IEiqfOz4RgtmBqRnXUffcjS2dhc7/z+FPZnM79Kej8eLHoVfxCyWRHFlzm93vEdv
16
+wxOCrD13EDOi08OOZfxWyIlCa6Bg8cMAKqQzd2OvQOWqlRWBTThBJIhWflU33izX
17
+Qn5GdmYqhfpc+9ZHHGhvXNydtRQkdxVK2dZNzLBvBlLlRmtoClU7xm3A+/5dddeP
18
+AQHEPtyFlUw49VYtZ3ru6KqPms7MKvcRhYLsy9rwSfuuniMlx4d0bDR7TOkw0QQS
19
+A0N8MGQRQpzl4mw4jLzyM5d5QtuGBh2P6hPGa0YQxtI3RPT/p6ENzzBiAKXiSfzo
20
+xw==
21
+-----END CERTIFICATE-----

+ 27
- 0
node_modules/socket.io/node_modules/policyfile/tests/ssl/ssl.private.key View File

@@ -0,0 +1,27 @@
1
+-----BEGIN RSA PRIVATE KEY-----
2
+MIIEowIBAAKCAQEAz+LXZOjcQCJq3+ZKUFabj71oo/ex/XsBcFqtBThjjTw9CVEV
3
+wfPQQp4XwtPiB204vnYXwQ1/R2NdTQqCZu47l79LssL/u2a5Y9+0NEU3nQA5qdt+
4
+1FAE0c5oexPimXOrR3GWfKz7PmZ2O0117IeCUUXPG5U8umhDe/4mDF4ZNJiKc404
5
+WthquTqgS7rLQZHhZ6D0EnGnOkzlmxJMYPNHSOY1/6ivdNUUcC87awNEA3lgfhy2
6
+5IyBK3QJc+aYKNTbt70Lery3bu2wWLFGtmNiGlQTS4JsxImRsECTI727ObS7/FWA
7
+QsqW+COL0Sa5BuMFrFIpjPrEe0ih7vRRbdmXRwIDAQABAoIBAGe4+9VqZfJN+dsq
8
+8Osyuz01uQ8OmC0sAWTIqUlQgENIyf9rCJsUBlYmwR5BT6Z69XP6QhHdpSK+TiAR
9
+XUz0EqG9HYzcxHIBaACP7j6iRoQ8R4kbbiWKo0z3WqQGIOqFjvD/mKEuQdE5mEYw
10
+eOUCG6BnX1WY2Yr8WKd2AA/tp0/Y4d8z04u9eodMpSTbHTzYMJb5SbBN1vo6FY7q
11
+8zSuO0BMzXlAxUsCwHsk1GQHFr8Oh3zIR7bQGtMBouI+6Lhh7sjFYsfxJboqMTBV
12
+IKaA216M6ggHG7MU1/jeKcMGDmEfqQLQoyWp29rMK6TklUgipME2L3UD7vTyAVzz
13
+xbVOpZkCgYEA8CXW4sZBBrSSrLR5SB+Ubu9qNTggLowOsC/kVKB2WJ4+xooc5HQo
14
+mFhq1v/WxPQoWIxdYsfg2odlL+JclK5Qcy6vXmRSdAQ5lK9gBDKxZSYc3NwAw2HA
15
+zyHCTK+I0n8PBYQ+yGcrxu0WqTGnlLW+Otk4CejO34WlgHwbH9bbY5UCgYEA3ZvT
16
+C4+OoMHXlmICSt29zUrYiL33IWsR3/MaONxTEDuvgkOSXXQOl/8Ebd6Nu+3WbsSN
17
+bjiPC/JyL1YCVmijdvFpl4gjtgvfJifs4G+QHvO6YfsYoVANk4u6g6rUuBIOwNK4
18
+RwYxwDc0oysp+g7tPxoSgDHReEVKJNzGBe9NGGsCgYEA4O4QP4gCEA3B9BF2J5+s
19
+n9uPVxmiyvZUK6Iv8zP4pThTBBMIzNIf09G9AHPQ7djikU2nioY8jXKTzC3xGTHM
20
+GJZ5m6fLsu7iH+nDvSreDSeNkTBfZqGAvoGYQ8uGE+L+ZuRfCcXYsxIOT5s6o4c3
21
+Dle2rVFpsuKzCY00urW796ECgYBn3go75+xEwrYGQSer6WR1nTgCV29GVYXKPooy
22
+zmmMOT1Yw80NSkEw0pFD4cTyqVYREsTrPU0mn1sPfrOXxnGfZSVFpcR/Je9QVfQ7
23
+eW7GYxwfom335aqHVj10SxRqteP+UoWWnHujCPz94VRKZMakBddYCIGSan+G6YdS
24
+7sdmwwKBgBc2qj0wvGXDF2kCLwSGfWoMf8CS1+5fIiUIdT1e/+7MfDdbmLMIFVjF
25
+QKS3zVViXCbrG5SY6wS9hxoc57f6E2A8vcaX6zy2xkZlGHQCpWRtEM5R01OWJQaH
26
+HsHMmQZGUQVoDm1oRkDhrTFK4K3ukc3rAxzeTZ96utOQN8/KJsTv
27
+-----END RSA PRIVATE KEY-----

+ 231
- 0
node_modules/socket.io/node_modules/policyfile/tests/unit.test.js View File

@@ -0,0 +1,231 @@
1
+var fspfs = require('../')
2
+  , fs = require('fs')
3
+  , http = require('http')
4
+  , https = require('https')
5
+  , net = require('net')
6
+  , should = require('should')
7
+  , assert = require('assert');
8
+
9
+module.exports = {
10
+  // Library version should be Semver compatible
11
+  'Library version': function(){
12
+     fspfs.version.should.match(/^\d+\.\d+\.\d+$/);
13
+  }
14
+
15
+  // Creating a server instace should not cause any problems
16
+  // either using the new Server or createServer method.
17
+, 'Create Server instance': function(){
18
+    var server = fspfs.createServer()
19
+      , server2 = new fspfs.Server({log:false}, ['blog.3rd-Eden.com:1337']);
20
+    
21
+    // server 2 options test
22
+    server2.log.should.be.false;
23
+    server2.origins.length.should.equal(1);
24
+    server2.origins[0].should.equal('blog.3rd-Eden.com:1337');
25
+    
26
+    // server defaults
27
+    (typeof server.log).should.be.equal('function');
28
+    server.origins.length.should.equal(1);
29
+    server.origins[0].should.equal('*:*');
30
+    
31
+    // instance checking, sanity check
32
+    assert.ok(server instanceof fspfs.Server);
33
+    assert.ok(!!server.buffer);
34
+    
35
+    // more options testing
36
+    server = fspfs.createServer(['blog.3rd-Eden.com:80']);
37
+    server.origins.length.should.equal(1);
38
+    server.origins[0].should.equal('blog.3rd-Eden.com:80');
39
+    
40
+    server = fspfs.createServer({log:false},['blog.3rd-Eden.com:80']);
41
+    server.log.should.be.false;
42
+    server.origins.length.should.equal(1);
43
+    server.origins[0].should.equal('blog.3rd-Eden.com:80');
44
+    
45
+  }
46
+
47
+, 'Add origin': function(){
48
+    var server = fspfs.createServer();
49
+    server.add('google.com:80', 'blog.3rd-Eden.com:1337');
50
+    
51
+    server.origins.length.should.equal(3);
52
+    server.origins.indexOf('google.com:80').should.be.above(0);
53
+    
54
+    // don't allow duplicates
55
+    server.add('google.com:80', 'google.com:80');
56
+    
57
+    var i = server.origins.length
58
+      , count = 0;
59
+    
60
+    while(i--){
61
+      if (server.origins[i] === 'google.com:80'){
62
+        count++;
63
+      }
64
+    }
65
+    
66
+    count.should.equal(1);
67
+  }
68
+
69
+, 'Remove origin': function(){
70
+    var server = fspfs.createServer();
71
+    server.add('google.com:80', 'blog.3rd-Eden.com:1337');
72
+    server.origins.length.should.equal(3);
73
+    
74
+    server.remove('google.com:80');
75
+    server.origins.length.should.equal(2);
76
+    server.origins.indexOf('google.com:80').should.equal(-1);
77
+  }
78
+
79
+, 'Buffer': function(){
80
+    var server = fspfs.createServer();
81
+    
82
+    Buffer.isBuffer(server.buffer).should.be.true;
83
+    server.buffer.toString().indexOf('to-ports="*"').should.be.above(0);
84
+    server.buffer.toString().indexOf('domain="*"').should.be.above(0);
85
+    server.buffer.toString().indexOf('domain="google.com"').should.equal(-1);
86
+    
87
+    // The buffers should be rebuild when new origins are added
88
+    server.add('google.com:80');
89
+    server.buffer.toString().indexOf('to-ports="80"').should.be.above(0);
90
+    server.buffer.toString().indexOf('domain="google.com"').should.be.above(0);
91
+    
92
+    server.remove('google.com:80');
93
+    server.buffer.toString().indexOf('to-ports="80"').should.equal(-1);
94
+    server.buffer.toString().indexOf('domain="google.com"').should.equal(-1);
95
+  }
96
+
97
+, 'Responder': function(){
98
+    var server = fspfs.createServer()
99
+      , calls = 0
100
+      // dummy socket to emulate a `real` socket
101
+      , dummySocket = {
102
+          readyState: 'open'
103
+        , end: function(buffer){
104
+          calls++;
105
+          Buffer.isBuffer(buffer).should.be.true;
106
+          buffer.toString().should.equal(server.buffer.toString());
107
+        }
108
+      };
109
+    
110
+    server.responder(dummySocket);
111
+    calls.should.equal(1);
112
+  }
113
+
114
+, 'Event proxy': function(){
115
+    var server = fspfs.createServer()
116
+      , calls = 0;
117
+    
118
+    Object.keys(process.EventEmitter.prototype).forEach(function proxy(key){
119
+      assert.ok(!!server[key] && typeof server[key] === 'function');
120
+    });
121
+    
122
+    // test if it works by calling a none default event
123
+    server.on('pew', function(){
124
+      calls++;
125
+    });
126
+    
127
+    server.emit('pew');
128
+    calls.should.equal(1);
129
+  }
130
+
131
+, 'inline response http': function(){
132
+    var port = 1335
133
+      , httpserver = http.createServer(function(q,r){r.writeHead(200);r.end(':3')})
134
+      , server = fspfs.createServer();
135
+    
136
+    httpserver.listen(port, function(){
137
+      server.listen(port + 1, httpserver, function(){
138
+        var client = net.createConnection(port);
139
+        client.write('<policy-file-request/>\0');
140
+        client.on('error', function(err){
141
+          assert.ok(!err, err)
142
+        });
143
+        client.on('data', function(data){
144
+        
145
+          var response = data.toString();
146
+          console.log(response);
147
+          
148
+          response.indexOf('to-ports="*"').should.be.above(0);
149
+          response.indexOf('domain="*"').should.be.above(0);
150
+          response.indexOf('domain="google.com"').should.equal(-1);
151
+          
152
+          // clean up
153
+          client.destroy();
154
+          server.close();
155
+          httpserver.close();
156
+        });
157
+      });
158
+    });
159
+  }
160
+
161
+, 'server response': function(){
162
+    var port = 1340
163
+      , server = fspfs.createServer();
164
+      
165
+    server.listen(port, function(){
166
+      var client = net.createConnection(port);
167
+      client.write('<policy-file-request/>\0');
168
+      client.on('error', function(err){
169
+        assert.ok(!err, err)
170
+      });
171
+      client.on('data', function(data){
172
+      
173
+        var response = data.toString();
174
+        
175
+        response.indexOf('to-ports="*"').should.be.above(0);
176
+        response.indexOf('domain="*"').should.be.above(0);
177
+        response.indexOf('domain="google.com"').should.equal(-1);
178
+        
179
+        // clean up
180
+        client.destroy();
181
+        server.close();
182
+      });
183
+    });
184
+  }
185
+
186
+, 'inline response https': function(){
187
+    var port = 1345
188
+      , ssl = {
189
+          key: fs.readFileSync(__dirname + '/ssl/ssl.private.key').toString()
190
+        , cert: fs.readFileSync(__dirname + '/ssl/ssl.crt').toString()
191
+        }
192
+      , httpserver = https.createServer(ssl, function(q,r){r.writeHead(200);r.end(':3')})
193
+      , server = fspfs.createServer();
194
+    
195
+    httpserver.listen(port, function(){
196
+      server.listen(port + 1, httpserver, function(){
197
+        var client = net.createConnection(port);
198
+        client.write('<policy-file-request/>\0');
199
+        client.on('error', function(err){
200
+          assert.ok(!err, err)
201
+        });
202
+        client.on('data', function(data){
203
+        
204
+          var response = data.toString();
205
+          
206
+          response.indexOf('to-ports="*"').should.be.above(0);
207
+          response.indexOf('domain="*"').should.be.above(0);
208
+          response.indexOf('domain="google.com"').should.equal(-1);
209
+          
210
+          // clean up
211
+          client.destroy();
212
+          server.close();
213
+          httpserver.close();
214
+        });
215
+      });
216
+    });
217
+  }
218
+
219
+, 'connect_failed': function(){
220
+    var server = fspfs.createServer();
221
+    
222
+    server.on('connect_failed', function(){
223
+      assert.ok(true);
224
+    });
225
+    
226
+    server.listen(function(){
227
+      assert.ok(false, 'Run this test without root access');
228
+      server.close();
229
+    });
230
+  }
231
+};

+ 1
- 0
node_modules/socket.io/node_modules/redis/.npmignore View File

@@ -0,0 +1 @@
1
+node_modules

+ 691
- 0
node_modules/socket.io/node_modules/redis/README.md View File

@@ -0,0 +1,691 @@
1
+redis - a node.js redis client
2
+===========================
3
+
4
+This is a complete Redis client for node.js.  It supports all Redis commands, including many recently added commands like EVAL from
5
+experimental Redis server branches.
6
+
7
+
8
+Install with:
9
+
10
+    npm install redis
11
+
12
+Pieter Noordhuis has provided a binding to the official `hiredis` C library, which is non-blocking and fast.  To use `hiredis`, do:
13
+
14
+    npm install hiredis redis
15
+
16
+If `hiredis` is installed, `node_redis` will use it by default.  Otherwise, a pure JavaScript parser will be used.
17
+
18
+If you use `hiredis`, be sure to rebuild it whenever you upgrade your version of node.  There are mysterious failures that can
19
+happen between node and native code modules after a node upgrade.
20
+
21
+
22
+## Usage
23
+
24
+Simple example, included as `examples/simple.js`:
25
+
26
+```js
27
+    var redis = require("redis"),
28
+        client = redis.createClient();
29
+
30
+    // if you'd like to select database 3, instead of 0 (default), call
31
+    // client.select(3, function() { /* ... */ });
32
+
33
+    client.on("error", function (err) {
34
+        console.log("Error " + err);
35
+    });
36
+
37
+    client.set("string key", "string val", redis.print);
38
+    client.hset("hash key", "hashtest 1", "some value", redis.print);
39
+    client.hset(["hash key", "hashtest 2", "some other value"], redis.print);
40
+    client.hkeys("hash key", function (err, replies) {
41
+        console.log(replies.length + " replies:");
42
+        replies.forEach(function (reply, i) {
43
+            console.log("    " + i + ": " + reply);
44
+        });
45
+        client.quit();
46
+    });
47
+```
48
+
49
+This will display:
50
+
51
+    mjr:~/work/node_redis (master)$ node example.js
52
+    Reply: OK
53
+    Reply: 0
54
+    Reply: 0
55
+    2 replies:
56
+        0: hashtest 1
57
+        1: hashtest 2
58
+    mjr:~/work/node_redis (master)$
59
+
60
+
61
+## Performance
62
+
63
+Here are typical results of `multi_bench.js` which is similar to `redis-benchmark` from the Redis distribution.
64
+It uses 50 concurrent connections with no pipelining.
65
+
66
+JavaScript parser:
67
+
68
+    PING: 20000 ops 42283.30 ops/sec 0/5/1.182
69
+    SET: 20000 ops 32948.93 ops/sec 1/7/1.515
70
+    GET: 20000 ops 28694.40 ops/sec 0/9/1.740
71
+    INCR: 20000 ops 39370.08 ops/sec 0/8/1.269
72
+    LPUSH: 20000 ops 36429.87 ops/sec 0/8/1.370
73
+    LRANGE (10 elements): 20000 ops 9891.20 ops/sec 1/9/5.048
74
+    LRANGE (100 elements): 20000 ops 1384.56 ops/sec 10/91/36.072
75
+
76
+hiredis parser:
77
+
78
+    PING: 20000 ops 46189.38 ops/sec 1/4/1.082
79
+    SET: 20000 ops 41237.11 ops/sec 0/6/1.210
80
+    GET: 20000 ops 39682.54 ops/sec 1/7/1.257
81
+    INCR: 20000 ops 40080.16 ops/sec 0/8/1.242
82
+    LPUSH: 20000 ops 41152.26 ops/sec 0/3/1.212
83
+    LRANGE (10 elements): 20000 ops 36563.07 ops/sec 1/8/1.363
84
+    LRANGE (100 elements): 20000 ops 21834.06 ops/sec 0/9/2.287
85
+
86
+The performance of `node_redis` improves dramatically with pipelining, which happens automatically in most normal programs.
87
+
88
+
89
+### Sending Commands
90
+
91
+Each Redis command is exposed as a function on the `client` object.
92
+All functions take either an `args` Array plus optional `callback` Function or
93
+a variable number of individual arguments followed by an optional callback.
94
+Here is an example of passing an array of arguments and a callback:
95
+
96
+    client.mset(["test keys 1", "test val 1", "test keys 2", "test val 2"], function (err, res) {});
97
+
98
+Here is that same call in the second style:
99
+
100
+    client.mset("test keys 1", "test val 1", "test keys 2", "test val 2", function (err, res) {});
101
+
102
+Note that in either form the `callback` is optional:
103
+
104
+    client.set("some key", "some val");
105
+    client.set(["some other key", "some val"]);
106
+
107
+If the key is missing, reply will be null (probably):
108
+
109
+    client.get("missingkey", function(err, reply) {
110
+        // reply is null when the key is missing
111
+        console.log(reply);
112
+    });
113
+
114
+For a list of Redis commands, see [Redis Command Reference](http://redis.io/commands)
115
+
116
+The commands can be specified in uppercase or lowercase for convenience.  `client.get()` is the same as `client.GET()`.
117
+
118
+Minimal parsing is done on the replies.  Commands that return a single line reply return JavaScript Strings,
119
+integer replies return JavaScript Numbers, "bulk" replies return node Buffers, and "multi bulk" replies return a
120
+JavaScript Array of node Buffers.  `HGETALL` returns an Object with Buffers keyed by the hash keys.
121
+
122
+# API
123
+
124
+## Connection Events
125
+
126
+`client` will emit some events about the state of the connection to the Redis server.
127
+
128
+### "ready"
129
+
130
+`client` will emit `ready` a connection is established to the Redis server and the server reports
131
+that it is ready to receive commands.  Commands issued before the `ready` event are queued,
132
+then replayed just before this event is emitted.
133
+
134
+### "connect"
135
+
136
+`client` will emit `connect` at the same time as it emits `ready` unless `client.options.no_ready_check`
137
+is set.  If this options is set, `connect` will be emitted when the stream is connected, and then
138
+you are free to try to send commands.
139
+
140
+### "error"
141
+
142
+`client` will emit `error` when encountering an error connecting to the Redis server.
143
+
144
+Note that "error" is a special event type in node.  If there are no listeners for an
145
+"error" event, node will exit.  This is usually what you want, but it can lead to some
146
+cryptic error messages like this:
147
+
148
+    mjr:~/work/node_redis (master)$ node example.js
149
+
150
+    node.js:50
151
+        throw e;
152
+        ^
153
+    Error: ECONNREFUSED, Connection refused
154
+        at IOWatcher.callback (net:870:22)
155
+        at node.js:607:9
156
+
157
+Not very useful in diagnosing the problem, but if your program isn't ready to handle this,
158
+it is probably the right thing to just exit.
159
+
160
+`client` will also emit `error` if an exception is thrown inside of `node_redis` for whatever reason.
161
+It would be nice to distinguish these two cases.
162
+
163
+### "end"
164
+
165
+`client` will emit `end` when an established Redis server connection has closed.
166
+
167
+### "drain"
168
+
169
+`client` will emit `drain` when the TCP connection to the Redis server has been buffering, but is now
170
+writable.  This event can be used to stream commands in to Redis and adapt to backpressure.  Right now,
171
+you need to check `client.command_queue.length` to decide when to reduce your send rate.  Then you can
172
+resume sending when you get `drain`.
173
+
174
+### "idle"
175
+
176
+`client` will emit `idle` when there are no outstanding commands that are awaiting a response.
177
+
178
+## redis.createClient(port, host, options)
179
+
180
+Create a new client connection.  `port` defaults to `6379` and `host` defaults
181
+to `127.0.0.1`.  If you have `redis-server` running on the same computer as node, then the defaults for
182
+port and host are probably fine.  `options` in an object with the following possible properties:
183
+
184
+* `parser`: which Redis protocol reply parser to use.  Defaults to `hiredis` if that module is installed.
185
+This may also be set to `javascript`.
186
+* `return_buffers`: defaults to `false`.  If set to `true`, then all replies will be sent to callbacks as node Buffer
187
+objects instead of JavaScript Strings.
188
+* `detect_buffers`: default to `false`. If set to `true`, then replies will be sent to callbacks as node Buffer objects
189
+if any of the input arguments to the original command were Buffer objects.
190
+This option lets you switch between Buffers and Strings on a per-command basis, whereas `return_buffers` applies to
191
+every command on a client.
192
+* `socket_nodelay`: defaults to `true`. Whether to call setNoDelay() on the TCP stream, which disables the
193
+Nagle algorithm on the underlying socket.  Setting this option to `false` can result in additional throughput at the
194
+cost of more latency.  Most applications will want this set to `true`.
195
+* `no_ready_check`: defaults to `false`. When a connection is established to the Redis server, the server might still
196
+be loading the database from disk.  While loading, the server not respond to any commands.  To work around this,
197
+`node_redis` has a "ready check" which sends the `INFO` command to the server.  The response from the `INFO` command
198
+indicates whether the server is ready for more commands.  When ready, `node_redis` emits a `ready` event.
199
+Setting `no_ready_check` to `true` will inhibit this check.
200
+* `enable_offline_queue`: defaults to `true`. By default, if there is no active
201
+connection to the redis server, commands are added to a queue and are executed
202
+once the connection has been established. Setting `enable_offline_queue` to
203
+`false` will disable this feature and the callback will be execute immediately
204
+with an error, or an error will be thrown if no callback is specified.
205
+
206
+```js
207
+    var redis = require("redis"),
208
+        client = redis.createClient(null, null, {detect_buffers: true});
209
+
210
+    client.set("foo_rand000000000000", "OK");
211
+
212
+    // This will return a JavaScript String
213
+    client.get("foo_rand000000000000", function (err, reply) {
214
+        console.log(reply.toString()); // Will print `OK`
215
+    });
216
+
217
+    // This will return a Buffer since original key is specified as a Buffer
218
+    client.get(new Buffer("foo_rand000000000000"), function (err, reply) {
219
+        console.log(reply.toString()); // Will print `<Buffer 4f 4b>`
220
+    });
221
+    client.end();
222
+```
223
+
224
+`createClient()` returns a `RedisClient` object that is named `client` in all of the examples here.
225
+
226
+## client.auth(password, callback)
227
+
228
+When connecting to Redis servers that require authentication, the `AUTH` command must be sent as the
229
+first command after connecting.  This can be tricky to coordinate with reconnections, the ready check,
230
+etc.  To make this easier, `client.auth()` stashes `password` and will send it after each connection,
231
+including reconnections.  `callback` is invoked only once, after the response to the very first
232
+`AUTH` command sent.
233
+NOTE: Your call to `client.auth()` should not be inside the ready handler. If
234
+you are doing this wrong, `client` will emit an error that looks
235
+something like this `Error: Ready check failed: ERR operation not permitted`.
236
+
237
+## client.end()
238
+
239
+Forcibly close the connection to the Redis server.  Note that this does not wait until all replies have been parsed.
240
+If you want to exit cleanly, call `client.quit()` to send the `QUIT` command after you have handled all replies.
241
+
242
+This example closes the connection to the Redis server before the replies have been read.  You probably don't
243
+want to do this:
244
+
245
+```js
246
+    var redis = require("redis"),
247
+        client = redis.createClient();
248
+
249
+    client.set("foo_rand000000000000", "some fantastic value");
250
+    client.get("foo_rand000000000000", function (err, reply) {
251
+        console.log(reply.toString());
252
+    });
253
+    client.end();
254
+```
255
+
256
+`client.end()` is useful for timeout cases where something is stuck or taking too long and you want
257
+to start over.
258
+
259
+## Friendlier hash commands
260
+
261
+Most Redis commands take a single String or an Array of Strings as arguments, and replies are sent back as a single String or an Array of Strings.
262
+When dealing with hash values, there are a couple of useful exceptions to this.
263
+
264
+### client.hgetall(hash)
265
+
266
+The reply from an HGETALL command will be converted into a JavaScript Object by `node_redis`.  That way you can interact
267
+with the responses using JavaScript syntax.
268
+
269
+Example:
270
+
271
+    client.hmset("hosts", "mjr", "1", "another", "23", "home", "1234");
272
+    client.hgetall("hosts", function (err, obj) {
273
+        console.dir(obj);
274
+    });
275
+
276
+Output:
277
+
278
+    { mjr: '1', another: '23', home: '1234' }
279
+
280
+### client.hmset(hash, obj, [callback])
281
+
282
+Multiple values in a hash can be set by supplying an object:
283
+
284
+    client.HMSET(key2, {
285
+        "0123456789": "abcdefghij", // NOTE: the key and value must both be strings
286
+        "some manner of key": "a type of value"
287
+    });
288
+
289
+The properties and values of this Object will be set as keys and values in the Redis hash.
290
+
291
+### client.hmset(hash, key1, val1, ... keyn, valn, [callback])
292
+
293
+Multiple values may also be set by supplying a list:
294
+
295
+    client.HMSET(key1, "0123456789", "abcdefghij", "some manner of key", "a type of value");
296
+
297
+
298
+## Publish / Subscribe
299
+
300
+Here is a simple example of the API for publish / subscribe.  This program opens two
301
+client connections, subscribes to a channel on one of them, and publishes to that
302
+channel on the other:
303
+
304
+```js
305
+    var redis = require("redis"),
306
+        client1 = redis.createClient(), client2 = redis.createClient(),
307
+        msg_count = 0;
308
+
309
+    client1.on("subscribe", function (channel, count) {
310
+        client2.publish("a nice channel", "I am sending a message.");
311
+        client2.publish("a nice channel", "I am sending a second message.");
312
+        client2.publish("a nice channel", "I am sending my last message.");
313
+    });
314
+
315
+    client1.on("message", function (channel, message) {
316
+        console.log("client1 channel " + channel + ": " + message);
317
+        msg_count += 1;
318
+        if (msg_count === 3) {
319
+            client1.unsubscribe();
320
+            client1.end();
321
+            client2.end();
322
+        }
323
+    });
324
+
325
+    client1.incr("did a thing");
326
+    client1.subscribe("a nice channel");
327
+```
328
+
329
+When a client issues a `SUBSCRIBE` or `PSUBSCRIBE`, that connection is put into "pub/sub" mode.
330
+At that point, only commands that modify the subscription set are valid.  When the subscription
331
+set is empty, the connection is put back into regular mode.
332
+
333
+If you need to send regular commands to Redis while in pub/sub mode, just open another connection.
334
+
335
+## Pub / Sub Events
336
+
337
+If a client has subscriptions active, it may emit these events:
338
+
339
+### "message" (channel, message)
340
+
341
+Client will emit `message` for every message received that matches an active subscription.
342
+Listeners are passed the channel name as `channel` and the message Buffer as `message`.
343
+
344
+### "pmessage" (pattern, channel, message)
345
+
346
+Client will emit `pmessage` for every message received that matches an active subscription pattern.
347
+Listeners are passed the original pattern used with `PSUBSCRIBE` as `pattern`, the sending channel
348
+name as `channel`, and the message Buffer as `message`.
349
+
350
+### "subscribe" (channel, count)
351
+
352
+Client will emit `subscribe` in response to a `SUBSCRIBE` command.  Listeners are passed the
353
+channel name as `channel` and the new count of subscriptions for this client as `count`.
354
+
355
+### "psubscribe" (pattern, count)
356
+
357
+Client will emit `psubscribe` in response to a `PSUBSCRIBE` command.  Listeners are passed the
358
+original pattern as `pattern`, and the new count of subscriptions for this client as `count`.
359
+
360
+### "unsubscribe" (channel, count)
361
+
362
+Client will emit `unsubscribe` in response to a `UNSUBSCRIBE` command.  Listeners are passed the
363
+channel name as `channel` and the new count of subscriptions for this client as `count`.  When
364
+`count` is 0, this client has left pub/sub mode and no more pub/sub events will be emitted.
365
+
366
+### "punsubscribe" (pattern, count)
367
+
368
+Client will emit `punsubscribe` in response to a `PUNSUBSCRIBE` command.  Listeners are passed the
369
+channel name as `channel` and the new count of subscriptions for this client as `count`.  When
370
+`count` is 0, this client has left pub/sub mode and no more pub/sub events will be emitted.
371
+
372
+## client.multi([commands])
373
+
374
+`MULTI` commands are queued up until an `EXEC` is issued, and then all commands are run atomically by
375
+Redis.  The interface in `node_redis` is to return an individual `Multi` object by calling `client.multi()`.
376
+
377
+```js
378
+    var redis  = require("./index"),
379
+        client = redis.createClient(), set_size = 20;
380
+
381
+    client.sadd("bigset", "a member");
382
+    client.sadd("bigset", "another member");
383
+
384
+    while (set_size > 0) {
385
+        client.sadd("bigset", "member " + set_size);
386
+        set_size -= 1;
387
+    }
388
+
389
+    // multi chain with an individual callback
390
+    client.multi()
391
+        .scard("bigset")
392
+        .smembers("bigset")
393
+        .keys("*", function (err, replies) {
394
+            // NOTE: code in this callback is NOT atomic
395
+            // this only happens after the the .exec call finishes.
396
+            client.mget(replies, redis.print);
397
+        })
398
+        .dbsize()
399
+        .exec(function (err, replies) {
400
+            console.log("MULTI got " + replies.length + " replies");
401
+            replies.forEach(function (reply, index) {
402
+                console.log("Reply " + index + ": " + reply.toString());
403
+            });
404
+        });
405
+```
406
+
407
+`client.multi()` is a constructor that returns a `Multi` object.  `Multi` objects share all of the
408
+same command methods as `client` objects do.  Commands are queued up inside the `Multi` object
409
+until `Multi.exec()` is invoked.
410
+
411
+You can either chain together `MULTI` commands as in the above example, or you can queue individual
412
+commands while still sending regular client command as in this example:
413
+
414
+```js
415
+    var redis  = require("redis"),
416
+        client = redis.createClient(), multi;
417
+
418
+    // start a separate multi command queue
419
+    multi = client.multi();
420
+    multi.incr("incr thing", redis.print);
421
+    multi.incr("incr other thing", redis.print);
422
+
423
+    // runs immediately
424
+    client.mset("incr thing", 100, "incr other thing", 1, redis.print);
425
+
426
+    // drains multi queue and runs atomically
427
+    multi.exec(function (err, replies) {
428
+        console.log(replies); // 101, 2
429
+    });
430
+
431
+    // you can re-run the same transaction if you like
432
+    multi.exec(function (err, replies) {
433
+        console.log(replies); // 102, 3
434
+        client.quit();
435
+    });
436
+```
437
+
438
+In addition to adding commands to the `MULTI` queue individually, you can also pass an array
439
+of commands and arguments to the constructor:
440
+
441
+```js
442
+    var redis  = require("redis"),
443
+        client = redis.createClient(), multi;
444
+
445
+    client.multi([
446
+        ["mget", "multifoo", "multibar", redis.print],
447
+        ["incr", "multifoo"],
448
+        ["incr", "multibar"]
449
+    ]).exec(function (err, replies) {
450
+        console.log(replies);
451
+    });
452
+```
453
+
454
+
455
+## Monitor mode
456
+
457
+Redis supports the `MONITOR` command, which lets you see all commands received by the Redis server
458
+across all client connections, including from other client libraries and other computers.
459
+
460
+After you send the `MONITOR` command, no other commands are valid on that connection.  `node_redis`
461
+will emit a `monitor` event for every new monitor message that comes across.  The callback for the
462
+`monitor` event takes a timestamp from the Redis server and an array of command arguments.
463
+
464
+Here is a simple example:
465
+
466
+```js
467
+    var client  = require("redis").createClient(),
468
+        util = require("util");
469
+
470
+    client.monitor(function (err, res) {
471
+        console.log("Entering monitoring mode.");
472
+    });
473
+
474
+    client.on("monitor", function (time, args) {
475
+        console.log(time + ": " + util.inspect(args));
476
+    });
477
+```
478
+
479
+# Extras
480
+
481
+Some other things you might like to know about.
482
+
483
+## client.server_info
484
+
485
+After the ready probe completes, the results from the INFO command are saved in the `client.server_info`
486
+object.
487
+
488
+The `versions` key contains an array of the elements of the version string for easy comparison.
489
+
490
+    > client.server_info.redis_version
491
+    '2.3.0'
492
+    > client.server_info.versions
493
+    [ 2, 3, 0 ]
494
+
495
+## redis.print()
496
+
497
+A handy callback function for displaying return values when testing.  Example:
498
+
499
+```js
500
+    var redis = require("redis"),
501
+        client = redis.createClient();
502
+
503
+    client.on("connect", function () {
504
+        client.set("foo_rand000000000000", "some fantastic value", redis.print);
505
+        client.get("foo_rand000000000000", redis.print);
506
+    });
507
+```
508
+
509
+This will print:
510
+
511
+    Reply: OK
512
+    Reply: some fantastic value
513
+
514
+Note that this program will not exit cleanly because the client is still connected.
515
+
516
+## redis.debug_mode
517
+
518
+Boolean to enable debug mode and protocol tracing.
519
+
520
+```js
521
+    var redis = require("redis"),
522
+        client = redis.createClient();
523
+
524
+    redis.debug_mode = true;
525
+
526
+    client.on("connect", function () {
527
+        client.set("foo_rand000000000000", "some fantastic value");
528
+    });
529
+```
530
+
531
+This will display:
532
+
533
+    mjr:~/work/node_redis (master)$ node ~/example.js
534
+    send command: *3
535
+    $3
536
+    SET
537
+    $20
538
+    foo_rand000000000000
539
+    $20
540
+    some fantastic value
541
+
542
+    on_data: +OK
543
+
544
+`send command` is data sent into Redis and `on_data` is data received from Redis.
545
+
546
+## client.send_command(command_name, args, callback)
547
+
548
+Used internally to send commands to Redis.  For convenience, nearly all commands that are published on the Redis
549
+Wiki have been added to the `client` object.  However, if I missed any, or if new commands are introduced before
550
+this library is updated, you can use `send_command()` to send arbitrary commands to Redis.
551
+
552
+All commands are sent as multi-bulk commands.  `args` can either be an Array of arguments, or omitted.
553
+
554
+## client.connected
555
+
556
+Boolean tracking the state of the connection to the Redis server.
557
+
558
+## client.command_queue.length
559
+
560
+The number of commands that have been sent to the Redis server but not yet replied to.  You can use this to
561
+enforce some kind of maximum queue depth for commands while connected.
562
+
563
+Don't mess with `client.command_queue` though unless you really know what you are doing.
564
+
565
+## client.offline_queue.length
566
+
567
+The number of commands that have been queued up for a future connection.  You can use this to enforce
568
+some kind of maximum queue depth for pre-connection commands.
569
+
570
+## client.retry_delay
571
+
572
+Current delay in milliseconds before a connection retry will be attempted.  This starts at `250`.
573
+
574
+## client.retry_backoff
575
+
576
+Multiplier for future retry timeouts.  This should be larger than 1 to add more time between retries.
577
+Defaults to 1.7.  The default initial connection retry is 250, so the second retry will be 425, followed by 723.5, etc.
578
+
579
+### Commands with Optional and Keyword arguments
580
+
581
+This applies to anything that uses an optional `[WITHSCORES]` or `[LIMIT offset count]` in the [redis.io/commands](http://redis.io/commands) documentation.
582
+
583
+Example:
584
+```js
585
+var args = [ 'myzset', 1, 'one', 2, 'two', 3, 'three', 99, 'ninety-nine' ];
586
+client.zadd(args, function (err, response) {
587
+    if (err) throw err;
588
+    console.log('added '+response+' items.');
589
+
590
+    // -Infinity and +Infinity also work
591
+    var args1 = [ 'myzset', '+inf', '-inf' ];
592
+    client.zrevrangebyscore(args1, function (err, response) {
593
+        if (err) throw err;
594
+        console.log('example1', response);
595
+        // write your code here
596
+    });
597
+
598
+    var max = 3, min = 1, offset = 1, count = 2;
599
+    var args2 = [ 'myzset', max, min, 'WITHSCORES', 'LIMIT', offset, count ];
600
+    client.zrevrangebyscore(args2, function (err, response) {
601
+        if (err) throw err;
602
+        console.log('example2', response);
603
+        // write your code here
604
+    });
605
+});
606
+```
607
+
608
+## TODO
609
+
610
+Better tests for auth, disconnect/reconnect, and all combinations thereof.
611
+
612
+Stream large set/get values into and out of Redis.  Otherwise the entire value must be in node's memory.
613
+
614
+Performance can be better for very large values.
615
+
616
+I think there are more performance improvements left in there for smaller values, especially for large lists of small values.
617
+
618
+## How to Contribute
619
+- open a pull request and then wait for feedback (if
620
+  [DTrejo](http://github.com/dtrejo) does not get back to you within 2 days,
621
+  comment again with indignation!)
622
+
623
+## Contributors
624
+Some people have have added features and fixed bugs in `node_redis` other than me.
625
+
626
+Ordered by date of first contribution.
627
+[Auto-generated](http://github.com/dtrejo/node-authors) on Wed Jul 25 2012 19:14:59 GMT-0700 (PDT).
628
+
629
+- [Matt Ranney aka `mranney`](https://github.com/mranney)
630
+- [Tim-Smart aka `tim-smart`](https://github.com/tim-smart)
631
+- [Tj Holowaychuk aka `visionmedia`](https://github.com/visionmedia)
632
+- [rick aka `technoweenie`](https://github.com/technoweenie)
633
+- [Orion Henry aka `orionz`](https://github.com/orionz)
634
+- [Aivo Paas aka `aivopaas`](https://github.com/aivopaas)
635
+- [Hank Sims aka `hanksims`](https://github.com/hanksims)
636
+- [Paul Carey aka `paulcarey`](https://github.com/paulcarey)
637
+- [Pieter Noordhuis aka `pietern`](https://github.com/pietern)
638
+- [nithesh aka `nithesh`](https://github.com/nithesh)
639
+- [Andy Ray aka `andy2ray`](https://github.com/andy2ray)
640
+- [unknown aka `unknowdna`](https://github.com/unknowdna)
641
+- [Dave Hoover aka `redsquirrel`](https://github.com/redsquirrel)
642
+- [Vladimir Dronnikov aka `dvv`](https://github.com/dvv)
643
+- [Umair Siddique aka `umairsiddique`](https://github.com/umairsiddique)
644
+- [Louis-Philippe Perron aka `lp`](https://github.com/lp)
645
+- [Mark Dawson aka `markdaws`](https://github.com/markdaws)
646
+- [Ian Babrou aka `bobrik`](https://github.com/bobrik)
647
+- [Felix Geisendörfer aka `felixge`](https://github.com/felixge)
648
+- [Jean-Hugues Pinson aka `undefined`](https://github.com/undefined)
649
+- [Maksim Lin aka `maks`](https://github.com/maks)
650
+- [Owen Smith aka `orls`](https://github.com/orls)
651
+- [Zachary Scott aka `zzak`](https://github.com/zzak)
652
+- [TEHEK Firefox aka `TEHEK`](https://github.com/TEHEK)
653
+- [Isaac Z. Schlueter aka `isaacs`](https://github.com/isaacs)
654
+- [David Trejo aka `DTrejo`](https://github.com/DTrejo)
655
+- [Brian Noguchi aka `bnoguchi`](https://github.com/bnoguchi)
656
+- [Philip Tellis aka `bluesmoon`](https://github.com/bluesmoon)
657
+- [Marcus Westin aka `marcuswestin2`](https://github.com/marcuswestin2)
658
+- [Jed Schmidt aka `jed`](https://github.com/jed)
659
+- [Dave Peticolas aka `jdavisp3`](https://github.com/jdavisp3)
660
+- [Trae Robrock aka `trobrock`](https://github.com/trobrock)
661
+- [Shankar Karuppiah aka `shankar0306`](https://github.com/shankar0306)
662
+- [Ignacio Burgueño aka `ignacio`](https://github.com/ignacio)
663
+
664
+Thanks.
665
+
666
+## LICENSE - "MIT License"
667
+
668
+Copyright (c) 2010 Matthew Ranney, http://ranney.com/
669
+
670
+Permission is hereby granted, free of charge, to any person
671
+obtaining a copy of this software and associated documentation
672
+files (the "Software"), to deal in the Software without
673
+restriction, including without limitation the rights to use,
674
+copy, modify, merge, publish, distribute, sublicense, and/or sell
675
+copies of the Software, and to permit persons to whom the
676
+Software is furnished to do so, subject to the following
677
+conditions:
678
+
679
+The above copyright notice and this permission notice shall be
680
+included in all copies or substantial portions of the Software.
681
+
682
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
683
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
684
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
685
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
686
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
687
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
688
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
689
+OTHER DEALINGS IN THE SOFTWARE.
690
+
691
+![spacer](http://ranney.com/1px.gif)

+ 89
- 0
node_modules/socket.io/node_modules/redis/benches/buffer_bench.js View File

@@ -0,0 +1,89 @@
1
+var source = new Buffer(100),
2
+    dest = new Buffer(100), i, j, k, tmp, count = 1000000, bytes = 100;
3
+    
4
+for (i = 99 ; i >= 0 ; i--) {
5
+    source[i] = 120;
6
+}
7
+
8
+var str = "This is a nice String.",
9
+    buf = new Buffer("This is a lovely Buffer.");
10
+
11
+var start = new Date();
12
+for (i = count * 100; i > 0 ; i--) {
13
+    if (Buffer.isBuffer(str)) {}
14
+}
15
+var end = new Date();
16
+console.log("Buffer.isBuffer(str) " + (end - start) + " ms");
17
+
18
+var start = new Date();
19
+for (i = count * 100; i > 0 ; i--) {
20
+    if (Buffer.isBuffer(buf)) {}
21
+}
22
+var end = new Date();
23
+console.log("Buffer.isBuffer(buf) " + (end - start) + " ms");
24
+
25
+var start = new Date();
26
+for (i = count * 100; i > 0 ; i--) {
27
+    if (str instanceof Buffer) {}
28
+}
29
+var end = new Date();
30
+console.log("str instanceof Buffer " + (end - start) + " ms");
31
+
32
+var start = new Date();
33
+for (i = count * 100; i > 0 ; i--) {
34
+    if (buf instanceof Buffer) {}
35
+}
36
+var end = new Date();
37
+console.log("buf instanceof Buffer " + (end - start) + " ms");
38
+
39
+for (i = bytes ; i > 0 ; i --) {
40
+    var start = new Date();
41
+    for (j = count ; j > 0; j--) {
42
+        tmp = source.toString("ascii", 0, bytes);
43
+    }
44
+    var end = new Date();
45
+    console.log("toString() " + i + " bytes " + (end - start) + " ms");
46
+}
47
+
48
+for (i = bytes ; i > 0 ; i --) {
49
+    var start = new Date();
50
+    for (j = count ; j > 0; j--) {
51
+        tmp = "";
52
+        for (k = 0; k <= i ; k++) {
53
+            tmp += String.fromCharCode(source[k]);
54
+        }
55
+    }
56
+    var end = new Date();
57
+    console.log("manual string " + i + " bytes " + (end - start) + " ms");
58
+}
59
+
60
+for (i = bytes ; i > 0 ; i--) {
61
+    var start = new Date();
62
+    for (j = count ; j > 0 ; j--) {
63
+        for (k = i ; k > 0 ; k--) {
64
+            dest[k] = source[k];
65
+        }
66
+    }
67
+    var end = new Date();
68
+    console.log("Manual copy " + i + " bytes " + (end - start) + " ms");
69
+}
70
+
71
+for (i = bytes ; i > 0 ; i--) {
72
+    var start = new Date();
73
+    for (j = count ; j > 0 ; j--) {
74
+        for (k = i ; k > 0 ; k--) {
75
+            dest[k] = 120;
76
+        }
77
+    }
78
+    var end = new Date();
79
+    console.log("Direct assignment " + i + " bytes " + (end - start) + " ms");
80
+}
81
+
82
+for (i = bytes ; i > 0 ; i--) {
83
+    var start = new Date();
84
+    for (j = count ; j > 0 ; j--) {
85
+        source.copy(dest, 0, 0, i);
86
+    }
87
+    var end = new Date();
88
+    console.log("Buffer.copy() " + i + " bytes " + (end - start) + " ms");
89
+}

+ 38
- 0
node_modules/socket.io/node_modules/redis/benches/hiredis_parser.js View File

@@ -0,0 +1,38 @@
1
+var Parser = require('../lib/parser/hiredis').Parser;
2
+var assert = require('assert');
3
+
4
+/*
5
+This test makes sure that exceptions thrown inside of "reply" event handlers
6
+are not trapped and mistakenly emitted as parse errors.
7
+*/
8
+(function testExecuteDoesNotCatchReplyCallbackExceptions() {
9
+  var parser = new Parser();
10
+  var replies = [{}];
11
+
12
+  parser.reader = {
13
+    feed: function() {},
14
+    get: function() {
15
+      return replies.shift();
16
+    }
17
+  };
18
+
19
+  var emittedError = false;
20
+  var caughtException = false;
21
+
22
+  parser
23
+    .on('error', function() {
24
+      emittedError = true;
25
+    })
26
+    .on('reply', function() {
27
+      throw new Error('bad');
28
+    });
29
+
30
+  try {
31
+    parser.execute();
32
+  } catch (err) {
33
+    caughtException = true;
34
+  }
35
+
36
+  assert.equal(caughtException, true);
37
+  assert.equal(emittedError, false);
38
+})();

+ 14
- 0
node_modules/socket.io/node_modules/redis/benches/re_sub_test.js View File

@@ -0,0 +1,14 @@
1
+var client = require('../index').createClient()
2
+  , client2 = require('../index').createClient()
3
+  , assert = require('assert');
4
+
5
+client.once('subscribe', function (channel, count) {
6
+  client.unsubscribe('x');
7
+  client.subscribe('x', function () {
8
+    client.quit();
9
+    client2.quit();
10
+  });
11
+  client2.publish('x', 'hi');
12
+});
13
+
14
+client.subscribe('x');

+ 29
- 0
node_modules/socket.io/node_modules/redis/benches/reconnect_test.js View File

@@ -0,0 +1,29 @@
1
+var redis = require("../index").createClient(null, null, {
2
+//    max_attempts: 4
3
+});
4
+
5
+redis.on("error", function (err) {
6
+    console.log("Redis says: " + err);
7
+});
8
+
9
+redis.on("ready", function () {
10
+    console.log("Redis ready.");
11
+});
12
+
13
+redis.on("reconnecting", function (arg) {
14
+    console.log("Redis reconnecting: " + JSON.stringify(arg));
15
+});
16
+redis.on("connect", function () {
17
+    console.log("Redis connected.");
18
+});
19
+
20
+setInterval(function () {
21
+    var now = Date.now();
22
+    redis.set("now", now, function (err, res) {
23
+        if (err) {
24
+            console.log(now + " Redis reply error: " + err);
25
+        } else {
26
+            console.log(now + " Redis reply: " + res);
27
+        }
28
+    });
29
+}, 100);

+ 16
- 0
node_modules/socket.io/node_modules/redis/benches/stress/codec.js View File

@@ -0,0 +1,16 @@
1
+var json = {
2
+	encode: JSON.stringify,
3
+	decode: JSON.parse
4
+};
5
+
6
+var MsgPack = require('node-msgpack');
7
+msgpack = {
8
+	encode: MsgPack.pack,
9
+	decode: function(str) { return MsgPack.unpack(new Buffer(str)); }
10
+};
11
+
12
+bison = require('bison');
13
+
14
+module.exports = json;
15
+//module.exports = msgpack;
16
+//module.exports = bison;

+ 38
- 0
node_modules/socket.io/node_modules/redis/benches/stress/pubsub/pub.js View File

@@ -0,0 +1,38 @@
1
+'use strict';
2
+
3
+var freemem = require('os').freemem;
4
+var profiler = require('v8-profiler');
5
+var codec = require('../codec');
6
+
7
+var sent = 0;
8
+
9
+var pub = require('redis').createClient(null, null, {
10
+	//command_queue_high_water: 5,
11
+	//command_queue_low_water: 1
12
+})
13
+.on('ready', function() {
14
+	this.emit('drain');
15
+})
16
+.on('drain', function() {
17
+	process.nextTick(exec);
18
+});
19
+
20
+var payload = '1'; for (var i = 0; i < 12; ++i) payload += payload;
21
+console.log('Message payload length', payload.length);
22
+
23
+function exec() {
24
+	pub.publish('timeline', codec.encode({ foo: payload }));
25
+	++sent;
26
+	if (!pub.should_buffer) {
27
+		process.nextTick(exec);
28
+	}
29
+}
30
+
31
+profiler.takeSnapshot('s_0');
32
+
33
+exec();
34
+
35
+setInterval(function() {
36
+	profiler.takeSnapshot('s_' + sent);
37
+	console.error('sent', sent, 'free', freemem(), 'cmdqlen', pub.command_queue.length, 'offqlen', pub.offline_queue.length);
38
+}, 2000);

+ 10
- 0
node_modules/socket.io/node_modules/redis/benches/stress/pubsub/run View File

@@ -0,0 +1,10 @@
1
+#!/bin/sh
2
+node server.js &
3
+node server.js &
4
+node server.js &
5
+node server.js &
6
+node server.js &
7
+node server.js &
8
+node server.js &
9
+node server.js &
10
+node --debug pub.js

+ 23
- 0
node_modules/socket.io/node_modules/redis/benches/stress/pubsub/server.js View File

@@ -0,0 +1,23 @@
1
+'use strict';
2
+
3
+var freemem = require('os').freemem;
4
+var codec = require('../codec');
5
+
6
+var id = Math.random();
7
+var recv = 0;
8
+
9
+var sub = require('redis').createClient()
10
+	.on('ready', function() {
11
+		this.subscribe('timeline');
12
+	})
13
+	.on('message', function(channel, message) {
14
+		var self = this;
15
+		if (message) {
16
+			message = codec.decode(message);
17
+			++recv;
18
+		}
19
+	});
20
+
21
+setInterval(function() {
22
+	console.error('id', id, 'received', recv, 'free', freemem());
23
+}, 2000);

+ 49
- 0
node_modules/socket.io/node_modules/redis/benches/stress/rpushblpop/pub.js View File

@@ -0,0 +1,49 @@
1
+'use strict';
2
+
3
+var freemem = require('os').freemem;
4
+//var profiler = require('v8-profiler');
5
+var codec = require('../codec');
6
+
7
+var sent = 0;
8
+
9
+var pub = require('redis').createClient(null, null, {
10
+	//command_queue_high_water: 5,
11
+	//command_queue_low_water: 1
12
+})
13
+.on('ready', function() {
14
+	this.del('timeline');
15
+	this.emit('drain');
16
+})
17
+.on('drain', function() {
18
+	process.nextTick(exec);
19
+});
20
+
21
+var payload = '1'; for (var i = 0; i < 12; ++i) payload += payload;
22
+console.log('Message payload length', payload.length);
23
+
24
+function exec() {
25
+	pub.rpush('timeline', codec.encode({ foo: payload }));
26
+	++sent;
27
+	if (!pub.should_buffer) {
28
+		process.nextTick(exec);
29
+	}
30
+}
31
+
32
+//profiler.takeSnapshot('s_0');
33
+
34
+exec();
35
+
36
+setInterval(function() {
37
+	//var ss = profiler.takeSnapshot('s_' + sent);
38
+	//console.error(ss.stringify());
39
+	pub.llen('timeline', function(err, result) {
40
+		console.error('sent', sent, 'free', freemem(),
41
+			'cmdqlen', pub.command_queue.length, 'offqlen', pub.offline_queue.length,
42
+			'llen', result
43
+		);
44
+	});
45
+}, 2000);
46
+
47
+/*setTimeout(function() {
48
+	process.exit();
49
+}, 30000);*/

+ 6
- 0
node_modules/socket.io/node_modules/redis/benches/stress/rpushblpop/run View File

@@ -0,0 +1,6 @@
1
+#!/bin/sh
2
+node server.js &
3
+#node server.js &
4
+#node server.js &
5
+#node server.js &
6
+node --debug pub.js

+ 30
- 0
node_modules/socket.io/node_modules/redis/benches/stress/rpushblpop/server.js View File

@@ -0,0 +1,30 @@
1
+'use strict';
2
+
3
+var freemem = require('os').freemem;
4
+var codec = require('../codec');
5
+
6
+var id = Math.random();
7
+var recv = 0;
8
+
9
+var cmd = require('redis').createClient();
10
+var sub = require('redis').createClient()
11
+	.on('ready', function() {
12
+		this.emit('timeline');
13
+	})
14
+	.on('timeline', function() {
15
+		var self = this;
16
+		this.blpop('timeline', 0, function(err, result) {
17
+			var message = result[1];
18
+			if (message) {
19
+				message = codec.decode(message);
20
+				++recv;
21
+			}
22
+			self.emit('timeline');
23
+		});
24
+	});
25
+
26
+setInterval(function() {
27
+	cmd.llen('timeline', function(err, result) {
28
+		console.error('id', id, 'received', recv, 'free', freemem(), 'llen', result);
29
+	});
30
+}, 2000);

+ 13
- 0
node_modules/socket.io/node_modules/redis/benches/stress/speed/00 View File

@@ -0,0 +1,13 @@
1
+# size	JSON				msgpack				bison
2
+26602	2151.0170848180414
3
+25542	?					2842.589272665782
4
+24835	?					?					7280.4538397469805
5
+6104	6985.234528557929
6
+5045	?					7217.461392841478
7
+4341	?					?					14261.406335354604
8
+4180	15864.633685636572
9
+4143	?					12954.806235781925
10
+4141	?					?					44650.70733912719
11
+75		114227.07313350472
12
+40		?					30162.440062810834
13
+39		?					?					119815.66013519121

+ 13
- 0
node_modules/socket.io/node_modules/redis/benches/stress/speed/plot View File

@@ -0,0 +1,13 @@
1
+#!/bin/sh
2
+
3
+gnuplot >size-rate.jpg << _EOF_
4
+
5
+set terminal png nocrop enhanced font verdana 12 size 640,480
6
+set logscale x
7
+set logscale y
8
+set grid
9
+set xlabel 'Serialized object size, octets'
10
+set ylabel 'decode(encode(obj)) rate, 1/sec'
11
+plot '00' using 1:2 title 'json' smooth bezier, '00' using 1:3 title 'msgpack' smooth bezier, '00' using 1:4 title 'bison' smooth bezier
12
+
13
+_EOF_

BIN
node_modules/socket.io/node_modules/redis/benches/stress/speed/size-rate.png View File


+ 84
- 0
node_modules/socket.io/node_modules/redis/benches/stress/speed/speed.js View File

@@ -0,0 +1,84 @@
1
+var msgpack = require('node-msgpack');
2
+var bison = require('bison');
3
+var codec = {
4
+	JSON: {
5
+		encode: JSON.stringify,
6
+		decode: JSON.parse
7
+	},
8
+	msgpack: {
9
+		encode: msgpack.pack,
10
+		decode: msgpack.unpack
11
+	},
12
+	bison: bison
13
+};
14
+
15
+var obj, l;
16
+
17
+var s = '0';
18
+for (var i = 0; i < 12; ++i) s += s;
19
+
20
+obj = {
21
+	foo: s,
22
+	arrrrrr: [{a:1,b:false,c:null,d:1.0}, 1111, 2222, 33333333],
23
+	rand: [],
24
+	a: s,
25
+	ccc: s,
26
+	b: s + s + s
27
+};
28
+for (i = 0; i < 100; ++i) obj.rand.push(Math.random());
29
+forObj(obj);
30
+
31
+obj = {
32
+	foo: s,
33
+	arrrrrr: [{a:1,b:false,c:null,d:1.0}, 1111, 2222, 33333333],
34
+	rand: []
35
+};
36
+for (i = 0; i < 100; ++i) obj.rand.push(Math.random());
37
+forObj(obj);
38
+
39
+obj = {
40
+	foo: s,
41
+	arrrrrr: [{a:1,b:false,c:null,d:1.0}, 1111, 2222, 33333333],
42
+	rand: []
43
+};
44
+forObj(obj);
45
+
46
+obj = {
47
+	arrrrrr: [{a:1,b:false,c:null,d:1.0}, 1111, 2222, 33333333],
48
+	rand: []
49
+};
50
+forObj(obj);
51
+
52
+function run(obj, codec) {
53
+	var t1 = Date.now();
54
+	var n = 10000;
55
+	for (var i = 0; i < n; ++i) {
56
+		codec.decode(l = codec.encode(obj));
57
+	}
58
+	var t2 = Date.now();
59
+	//console.log('DONE', n*1000/(t2-t1), 'codecs/sec, length=', l.length);
60
+	return [n*1000/(t2-t1), l.length];
61
+}
62
+
63
+function series(obj, cname, n) {
64
+	var rate = 0;
65
+	var len = 0;
66
+	for (var i = 0; i < n; ++i) {
67
+		var r = run(obj, codec[cname]);
68
+		rate += r[0];
69
+		len += r[1];
70
+	}
71
+	rate /= n;
72
+	len /= n;
73
+	console.log(cname + '	' + rate + '	' + len);
74
+	return [rate, len];
75
+}
76
+
77
+function forObj(obj) {
78
+	var r = {
79
+		JSON: series(obj, 'JSON', 20),
80
+		msgpack: series(obj, 'msgpack', 20),
81
+		bison: series(obj, 'bison', 20)
82
+	};
83
+	return r;
84
+}

+ 18
- 0
node_modules/socket.io/node_modules/redis/benches/sub_quit_test.js View File

@@ -0,0 +1,18 @@
1
+var client = require("redis").createClient(),
2
+    client2 = require("redis").createClient();
3
+
4
+client.subscribe("something");
5
+client.on("subscribe", function (channel, count) {
6
+    console.log("Got sub: " + channel);
7
+    client.unsubscribe("something");
8
+});
9
+
10
+client.on("unsubscribe", function (channel, count) {
11
+    console.log("Got unsub: " + channel + ", quitting");
12
+    client.quit();
13
+});
14
+
15
+// exercise unsub before sub
16
+client2.unsubscribe("something");
17
+client2.subscribe("another thing");
18
+client2.quit();

+ 219
- 0
node_modules/socket.io/node_modules/redis/changelog.md View File

@@ -0,0 +1,219 @@
1
+Changelog
2
+=========
3
+
4
+## v0.7.2 - April 29, 2012
5
+
6
+Many contributed fixes. Thank you, contributors.
7
+
8
+* [GH-190] - pub/sub mode fix (Brian Noguchi)
9
+* [GH-165] - parser selection fix (TEHEK)
10
+* numerous documentation and examples updates
11
+* auth errors emit Errors instead of Strings (David Trejo)
12
+
13
+## v0.7.1 - November 15, 2011
14
+
15
+Fix regression in reconnect logic.
16
+
17
+Very much need automated tests for reconnection and queue logic.
18
+
19
+## v0.7.0 - November 14, 2011
20
+
21
+Many contributed fixes. Thanks everybody.
22
+
23
+* [GH-127] - properly re-initialize parser on reconnect
24
+* [GH-136] - handle passing undefined as callback (Ian Babrou)
25
+* [GH-139] - properly handle exceptions thrown in pub/sub event handlers (Felix Geisendörfer)
26
+* [GH-141] - detect closing state on stream error (Felix Geisendörfer)
27
+* [GH-142] - re-select database on reconnection (Jean-Hugues Pinson)
28
+* [GH-146] - add sort example (Maksim Lin)
29
+
30
+Some more goodies:
31
+
32
+* Fix bugs with node 0.6
33
+* Performance improvements
34
+* New version of `multi_bench.js` that tests more realistic scenarios
35
+* [GH-140] - support optional callback for subscribe commands
36
+* Properly flush and error out command queue when connection fails
37
+* Initial work on reconnection thresholds
38
+
39
+## v0.6.7 - July 30, 2011
40
+
41
+(accidentally skipped v0.6.6)
42
+
43
+Fix and test for [GH-123]
44
+
45
+Passing an Array as as the last argument should expand as users
46
+expect.  The old behavior was to coerce the arguments into Strings,
47
+which did surprising things with Arrays.
48
+
49
+## v0.6.5 - July 6, 2011
50
+
51
+Contributed changes:
52
+
53
+*  Support SlowBuffers (Umair Siddique)
54
+*  Add Multi to exports (Louis-Philippe Perron)
55
+*  Fix for drain event calculation (Vladimir Dronnikov)
56
+
57
+Thanks!
58
+
59
+## v0.6.4 - June 30, 2011
60
+
61
+Fix bug with optional callbacks for hmset.
62
+
63
+## v0.6.2 - June 30, 2011
64
+
65
+Bugs fixed:
66
+
67
+*  authentication retry while server is loading db (danmaz74) [GH-101]
68
+*  command arguments processing issue with arrays
69
+
70
+New features:
71
+
72
+*  Auto update of new commands from redis.io (Dave Hoover)
73
+*  Performance improvements and backpressure controls.
74
+*  Commands now return the true/false value from the underlying socket write(s).
75
+*  Implement command_queue high water and low water for more better control of queueing.
76
+
77
+See `examples/backpressure_drain.js` for more information.
78
+
79
+## v0.6.1 - June 29, 2011
80
+
81
+Add support and tests for Redis scripting through EXEC command.
82
+
83
+Bug fix for monitor mode.  (forddg)
84
+
85
+Auto update of new commands from redis.io (Dave Hoover)
86
+
87
+## v0.6.0 - April 21, 2011
88
+
89
+Lots of bugs fixed.
90
+
91
+*  connection error did not properly trigger reconnection logic [GH-85]
92
+*  client.hmget(key, [val1, val2]) was not expanding properly [GH-66]
93
+*  client.quit() while in pub/sub mode would throw an error [GH-87]
94
+*  client.multi(['hmset', 'key', {foo: 'bar'}]) fails [GH-92]
95
+*  unsubscribe before subscribe would make things very confused [GH-88]
96
+*  Add BRPOPLPUSH [GH-79]
97
+
98
+## v0.5.11 - April 7, 2011
99
+
100
+Added DISCARD
101
+
102
+I originally didn't think DISCARD would do anything here because of the clever MULTI interface, but somebody
103
+pointed out to me that DISCARD can be used to flush the WATCH set.
104
+
105
+## v0.5.10 - April 6, 2011
106
+
107
+Added HVALS
108
+
109
+## v0.5.9 - March 14, 2011
110
+
111
+Fix bug with empty Array arguments - Andy Ray
112
+
113
+## v0.5.8 - March 14, 2011
114
+
115
+Add `MONITOR` command and special monitor command reply parsing.
116
+
117
+## v0.5.7 - February 27, 2011
118
+
119
+Add magical auth command.
120
+
121
+Authentication is now remembered by the client and will be automatically sent to the server
122
+on every connection, including any reconnections.
123
+
124
+## v0.5.6 - February 22, 2011
125
+
126
+Fix bug in ready check with `return_buffers` set to `true`.
127
+
128
+Thanks to Dean Mao and Austin Chau.
129
+
130
+## v0.5.5 - February 16, 2011
131
+
132
+Add probe for server readiness.
133
+
134
+When a Redis server starts up, it might take a while to load the dataset into memory.
135
+During this time, the server will accept connections, but will return errors for all non-INFO
136
+commands.  Now node_redis will send an INFO command whenever it connects to a server.
137
+If the info command indicates that the server is not ready, the client will keep trying until
138
+the server is ready.  Once it is ready, the client will emit a "ready" event as well as the
139
+"connect" event.  The client will queue up all commands sent before the server is ready, just
140
+like it did before.  When the server is ready, all offline/non-ready commands will be replayed.
141
+This should be backward compatible with previous versions.
142
+
143
+To disable this ready check behavior, set `options.no_ready_check` when creating the client.
144
+
145
+As a side effect of this change, the key/val params from the info command are available as
146
+`client.server_options`.  Further, the version string is decomposed into individual elements
147
+in `client.server_options.versions`.
148
+
149
+## v0.5.4 - February 11, 2011
150
+
151
+Fix excess memory consumption from Queue backing store.
152
+
153
+Thanks to Gustaf Sjöberg.
154
+
155
+## v0.5.3 - February 5, 2011
156
+
157
+Fix multi/exec error reply callback logic.
158
+
159
+Thanks to Stella Laurenzo.
160
+
161
+## v0.5.2 - January 18, 2011
162
+
163
+Fix bug where unhandled error replies confuse the parser.
164
+
165
+## v0.5.1 - January 18, 2011
166
+
167
+Fix bug where subscribe commands would not handle redis-server startup error properly.
168
+
169
+## v0.5.0 - December 29, 2010
170
+
171
+Some bug fixes:
172
+
173
+* An important bug fix in reconnection logic.  Previously, reply callbacks would be invoked twice after
174
+  a reconnect.
175
+* Changed error callback argument to be an actual Error object.
176
+
177
+New feature:
178
+
179
+* Add friendly syntax for HMSET using an object.
180
+
181
+## v0.4.1 - December 8, 2010
182
+
183
+Remove warning about missing hiredis.  You probably do want it though.
184
+
185
+## v0.4.0 - December 5, 2010
186
+
187
+Support for multiple response parsers and hiredis C library from Pieter Noordhuis.
188
+Return Strings instead of Buffers by default.
189
+Empty nested mb reply bug fix.
190
+
191
+## v0.3.9 - November 30, 2010
192
+
193
+Fix parser bug on failed EXECs.
194
+
195
+## v0.3.8 - November 10, 2010
196
+
197
+Fix for null MULTI response when WATCH condition fails.
198
+
199
+## v0.3.7 - November 9, 2010
200
+
201
+Add "drain" and "idle" events.
202
+
203
+## v0.3.6 - November 3, 2010
204
+
205
+Add all known Redis commands from Redis master, even ones that are coming in 2.2 and beyond.
206
+
207
+Send a friendlier "error" event message on stream errors like connection refused / reset.
208
+
209
+## v0.3.5 - October 21, 2010
210
+
211
+A few bug fixes.
212
+
213
+* Fixed bug with `nil` multi-bulk reply lengths that showed up with `BLPOP` timeouts.
214
+* Only emit `end` once when connection goes away.
215
+* Fixed bug in `test.js` where driver finished before all tests completed.
216
+
217
+## unversioned wasteland
218
+
219
+See the git history for what happened before.

+ 87
- 0
node_modules/socket.io/node_modules/redis/diff_multi_bench_output.js View File

@@ -0,0 +1,87 @@
1
+#!/usr/bin/env node
2
+
3
+var colors = require('colors'),
4
+    fs = require('fs'),
5
+    _ = require('underscore'),
6
+    metrics = require('metrics'),
7
+
8
+    // `node diff_multi_bench_output.js before.txt after.txt`
9
+    before = process.argv[2],
10
+    after = process.argv[3];
11
+
12
+if (!before || !after) {
13
+    console.log('Please supply two file arguments:');
14
+    var n = __filename;
15
+    n = n.substring(n.lastIndexOf('/', n.length));
16
+    console.log('    ./' + n + ' multiBenchBefore.txt multiBenchAfter.txt');
17
+    console.log('To generate multiBenchBefore.txt, run');
18
+    console.log('    node multi_bench.js > multiBenchBefore.txt');
19
+    console.log('Thank you for benchmarking responsibly.');
20
+    return;
21
+}
22
+
23
+var before_lines = fs.readFileSync(before, 'utf8').split('\n'),
24
+    after_lines = fs.readFileSync(after, 'utf8').split('\n');
25
+
26
+console.log('Comparing before,', before.green, '(', before_lines.length,
27
+    'lines)', 'to after,', after.green, '(', after_lines.length, 'lines)');
28
+
29
+var total_ops = new metrics.Histogram.createUniformHistogram();
30
+
31
+before_lines.forEach(function(b, i) {
32
+    var a = after_lines[i];
33
+    if (!a || !b || !b.trim() || !a.trim()) {
34
+        // console.log('#ignored#', '>'+a+'<', '>'+b+'<');
35
+        return;
36
+    }
37
+
38
+    b_words = b.split(' ').filter(is_whitespace);
39
+    a_words = a.split(' ').filter(is_whitespace);
40
+
41
+    var ops =
42
+        [b_words, a_words]
43
+        .map(function(words) {
44
+            // console.log(words);
45
+            return parseInt10(words.slice(-2, -1));
46
+        }).filter(function(num) {
47
+            var isNaN = !num && num !== 0;
48
+            return !isNaN;
49
+        });
50
+    if (ops.length != 2) return
51
+
52
+    var delta = ops[1] - ops[0];
53
+
54
+    total_ops.update(delta);
55
+
56
+    delta = humanize_diff(delta);
57
+    console.log(
58
+        // name of test
59
+        command_name(a_words) == command_name(b_words)
60
+            ? command_name(a_words) + ':'
61
+            : '404:',
62
+        // results of test
63
+        ops.join(' -> '), 'ops/sec (∆', delta, ')');
64
+});
65
+
66
+console.log('Mean difference in ops/sec:', humanize_diff(total_ops.mean()));
67
+
68
+function is_whitespace(s) {
69
+    return !!s.trim();
70
+}
71
+
72
+function parseInt10(s) {
73
+    return parseInt(s, 10);
74
+}
75
+
76
+// green if greater than 0, red otherwise
77
+function humanize_diff(num) {
78
+    if (num > 0) {
79
+        return ('+' + num).green;
80
+    }
81
+    return ('' + num).red;
82
+}
83
+
84
+function command_name(words) {
85
+    var line = words.join(' ');
86
+    return line.substr(0, line.indexOf(','));
87
+}

+ 5
- 0
node_modules/socket.io/node_modules/redis/examples/auth.js View File

@@ -0,0 +1,5 @@
1
+var redis  = require("redis"),
2
+    client = redis.createClient();
3
+
4
+// This command is magical.  Client stashes the password and will issue on every connect.
5
+client.auth("somepass");

+ 33
- 0
node_modules/socket.io/node_modules/redis/examples/backpressure_drain.js View File

@@ -0,0 +1,33 @@
1
+var redis = require("../index"),
2
+    client = redis.createClient(null, null, {
3
+        command_queue_high_water: 5,
4
+        command_queue_low_water: 1
5
+    }),
6
+    remaining_ops = 100000, paused = false;
7
+
8
+function op() {
9
+    if (remaining_ops <= 0) {
10
+        console.error("Finished.");
11
+        process.exit(0);
12
+    }
13
+
14
+    remaining_ops--;
15
+    if (client.hset("test hash", "val " + remaining_ops, remaining_ops) === false) {
16
+        console.log("Pausing at " + remaining_ops);
17
+        paused = true;
18
+    } else {
19
+        process.nextTick(op);
20
+    }
21
+}
22
+
23
+client.on("drain", function () {
24
+    if (paused) {
25
+        console.log("Resuming at " + remaining_ops);
26
+        paused = false;
27
+        process.nextTick(op);
28
+    } else {
29
+        console.log("Got drain while not paused at " + remaining_ops);
30
+    }
31
+});
32
+
33
+op();

+ 9
- 0
node_modules/socket.io/node_modules/redis/examples/eval.js View File

@@ -0,0 +1,9 @@
1
+var redis = require("./index"),
2
+    client = redis.createClient();
3
+
4
+redis.debug_mode = true;
5
+
6
+client.eval("return 100.5", 0, function (err, res) {
7
+    console.dir(err);
8
+    console.dir(res);
9
+});

+ 24
- 0
node_modules/socket.io/node_modules/redis/examples/extend.js View File

@@ -0,0 +1,24 @@
1
+var redis = require("redis"),
2
+    client = redis.createClient();
3
+
4
+// Extend the RedisClient prototype to add a custom method
5
+// This one converts the results from "INFO" into a JavaScript Object
6
+
7
+redis.RedisClient.prototype.parse_info = function (callback) {
8
+    this.info(function (err, res) {
9
+        var lines = res.toString().split("\r\n").sort();
10
+        var obj = {};
11
+        lines.forEach(function (line) {
12
+            var parts = line.split(':');
13
+            if (parts[1]) {
14
+                obj[parts[0]] = parts[1];
15
+            }
16
+        });
17
+        callback(obj)
18
+    });
19
+};
20
+
21
+client.parse_info(function (info) {
22
+    console.dir(info);
23
+    client.quit();
24
+});

+ 32
- 0
node_modules/socket.io/node_modules/redis/examples/file.js View File

@@ -0,0 +1,32 @@
1
+// Read a file from disk, store it in Redis, then read it back from Redis.
2
+
3
+var redis = require("redis"),
4
+    client = redis.createClient(),
5
+    fs = require("fs"),
6
+    filename = "kids_in_cart.jpg";
7
+
8
+// Get the file I use for testing like this:
9
+//    curl http://ranney.com/kids_in_cart.jpg -o kids_in_cart.jpg
10
+// or just use your own file.
11
+
12
+// Read a file from fs, store it in Redis, get it back from Redis, write it back to fs.
13
+fs.readFile(filename, function (err, data) {
14
+    if (err) throw err
15
+    console.log("Read " + data.length + " bytes from filesystem.");
16
+    
17
+    client.set(filename, data, redis.print); // set entire file
18
+    client.get(filename, function (err, reply) { // get entire file
19
+        if (err) {
20
+            console.log("Get error: " + err);
21
+        } else {
22
+            fs.writeFile("duplicate_" + filename, reply, function (err) {
23
+                if (err) {
24
+                    console.log("Error on write: " + err)
25
+                } else {
26
+                    console.log("File written.");
27
+                }
28
+                client.end();
29
+            });
30
+        }
31
+    });
32
+});

+ 5
- 0
node_modules/socket.io/node_modules/redis/examples/mget.js View File

@@ -0,0 +1,5 @@
1
+var client = require("redis").createClient();
2
+
3
+client.mget(["sessions started", "sessions started", "foo"], function (err, res) {
4
+    console.dir(res);
5
+});

+ 10
- 0
node_modules/socket.io/node_modules/redis/examples/monitor.js View File

@@ -0,0 +1,10 @@
1
+var client  = require("../index").createClient(),
2
+    util = require("util");
3
+
4
+client.monitor(function (err, res) {
5
+    console.log("Entering monitoring mode.");
6
+});
7
+
8
+client.on("monitor", function (time, args) {
9
+    console.log(time + ": " + util.inspect(args));
10
+});

+ 46
- 0
node_modules/socket.io/node_modules/redis/examples/multi.js View File

@@ -0,0 +1,46 @@
1
+var redis  = require("redis"),
2
+    client = redis.createClient(), set_size = 20;
3
+
4
+client.sadd("bigset", "a member");
5
+client.sadd("bigset", "another member");
6
+
7
+while (set_size > 0) {
8
+    client.sadd("bigset", "member " + set_size);
9
+    set_size -= 1;
10
+}
11
+
12
+// multi chain with an individual callback
13
+client.multi()
14
+    .scard("bigset")
15
+    .smembers("bigset")
16
+    .keys("*", function (err, replies) {
17
+        client.mget(replies, redis.print);
18
+    })
19
+    .dbsize()
20
+    .exec(function (err, replies) {
21
+        console.log("MULTI got " + replies.length + " replies");
22
+        replies.forEach(function (reply, index) {
23
+            console.log("Reply " + index + ": " + reply.toString());
24
+        });
25
+    });
26
+
27
+client.mset("incr thing", 100, "incr other thing", 1, redis.print);
28
+
29
+// start a separate multi command queue
30
+var multi = client.multi();
31
+multi.incr("incr thing", redis.print);
32
+multi.incr("incr other thing", redis.print);
33
+
34
+// runs immediately
35
+client.get("incr thing", redis.print); // 100
36
+
37
+// drains multi queue and runs atomically
38
+multi.exec(function (err, replies) {
39
+    console.log(replies); // 101, 2
40
+});
41
+
42
+// you can re-run the same transaction if you like
43
+multi.exec(function (err, replies) {
44
+    console.log(replies); // 102, 3
45
+    client.quit();
46
+});

+ 29
- 0
node_modules/socket.io/node_modules/redis/examples/multi2.js View File

@@ -0,0 +1,29 @@
1
+var redis  = require("redis"),
2
+    client = redis.createClient(), multi;
3
+
4
+// start a separate command queue for multi
5
+multi = client.multi();
6
+multi.incr("incr thing", redis.print);
7
+multi.incr("incr other thing", redis.print);
8
+
9
+// runs immediately
10
+client.mset("incr thing", 100, "incr other thing", 1, redis.print);
11
+
12
+// drains multi queue and runs atomically
13
+multi.exec(function (err, replies) {
14
+    console.log(replies); // 101, 2
15
+});
16
+
17
+// you can re-run the same transaction if you like
18
+multi.exec(function (err, replies) {
19
+    console.log(replies); // 102, 3
20
+    client.quit();
21
+});
22
+
23
+client.multi([
24
+    ["mget", "multifoo", "multibar", redis.print],
25
+    ["incr", "multifoo"],
26
+    ["incr", "multibar"]
27
+]).exec(function (err, replies) {
28
+    console.log(replies.toString());
29
+});

+ 33
- 0
node_modules/socket.io/node_modules/redis/examples/psubscribe.js View File

@@ -0,0 +1,33 @@
1
+var redis = require("redis"),
2
+    client1 = redis.createClient(),
3
+    client2 = redis.createClient(),
4
+    client3 = redis.createClient(),
5
+    client4 = redis.createClient(),
6
+    msg_count = 0;
7
+
8
+redis.debug_mode = false;
9
+
10
+client1.on("psubscribe", function (pattern, count) {
11
+    console.log("client1 psubscribed to " + pattern + ", " + count + " total subscriptions");
12
+    client2.publish("channeltwo", "Me!");
13
+    client3.publish("channelthree", "Me too!");
14
+    client4.publish("channelfour", "And me too!");
15
+});
16
+
17
+client1.on("punsubscribe", function (pattern, count) {
18
+    console.log("client1 punsubscribed from " + pattern + ", " + count + " total subscriptions");
19
+    client4.end();
20
+    client3.end();
21
+    client2.end();
22
+    client1.end();
23
+});
24
+
25
+client1.on("pmessage", function (pattern, channel, message) {
26
+    console.log("("+  pattern +")" + " client1 received message on " + channel + ": " + message);
27
+    msg_count += 1;
28
+    if (msg_count === 3) {
29
+        client1.punsubscribe();
30
+    }
31
+});
32
+
33
+client1.psubscribe("channel*");

+ 41
- 0
node_modules/socket.io/node_modules/redis/examples/pub_sub.js View File

@@ -0,0 +1,41 @@
1
+var redis = require("redis"),
2
+    client1 = redis.createClient(), msg_count = 0,
3
+    client2 = redis.createClient();
4
+
5
+redis.debug_mode = false;
6
+
7
+// Most clients probably don't do much on "subscribe".  This example uses it to coordinate things within one program.
8
+client1.on("subscribe", function (channel, count) {
9
+    console.log("client1 subscribed to " + channel + ", " + count + " total subscriptions");
10
+    if (count === 2) {
11
+        client2.publish("a nice channel", "I am sending a message.");
12
+        client2.publish("another one", "I am sending a second message.");
13
+        client2.publish("a nice channel", "I am sending my last message.");
14
+    }
15
+});
16
+
17
+client1.on("unsubscribe", function (channel, count) {
18
+    console.log("client1 unsubscribed from " + channel + ", " + count + " total subscriptions");
19
+    if (count === 0) {
20
+        client2.end();
21
+        client1.end();
22
+    }
23
+});
24
+
25
+client1.on("message", function (channel, message) {
26
+    console.log("client1 channel " + channel + ": " + message);
27
+    msg_count += 1;
28
+    if (msg_count === 3) {
29
+        client1.unsubscribe();
30
+    }
31
+});
32
+
33
+client1.on("ready", function () {
34
+    // if you need auth, do it here
35
+    client1.incr("did a thing");
36
+    client1.subscribe("a nice channel", "another one");
37
+});
38
+
39
+client2.on("ready", function () {
40
+    // if you need auth, do it here
41
+});

+ 24
- 0
node_modules/socket.io/node_modules/redis/examples/simple.js View File

@@ -0,0 +1,24 @@
1
+var redis = require("redis"),
2
+    client = redis.createClient();
3
+
4
+client.on("error", function (err) {
5
+    console.log("error event - " + client.host + ":" + client.port + " - " + err);
6
+});
7
+
8
+client.set("string key", "string val", redis.print);
9
+client.hset("hash key", "hashtest 1", "some value", redis.print);
10
+client.hset(["hash key", "hashtest 2", "some other value"], redis.print);
11
+client.hkeys("hash key", function (err, replies) {
12
+    if (err) {
13
+        return console.error("error response - " + err);
14
+    }
15
+
16
+    console.log(replies.length + " replies:");
17
+    replies.forEach(function (reply, i) {
18
+        console.log("    " + i + ": " + reply);
19
+    });
20
+});
21
+
22
+client.quit(function (err, res) {
23
+    console.log("Exiting from quit command.");
24
+});

+ 17
- 0
node_modules/socket.io/node_modules/redis/examples/sort.js View File

@@ -0,0 +1,17 @@
1
+var redis = require("redis"),
2
+    client = redis.createClient();
3
+
4
+client.sadd("mylist", 1);
5
+client.sadd("mylist", 2);
6
+client.sadd("mylist", 3);
7
+
8
+client.set("weight_1", 5);
9
+client.set("weight_2", 500);
10
+client.set("weight_3", 1);
11
+
12
+client.set("object_1", "foo");
13
+client.set("object_2", "bar");
14
+client.set("object_3", "qux");
15
+
16
+client.sort("mylist", "by", "weight_*", "get", "object_*", redis.print);
17
+// Prints Reply: qux,foo,bar

+ 15
- 0
node_modules/socket.io/node_modules/redis/examples/subqueries.js View File

@@ -0,0 +1,15 @@
1
+// Sending commands in response to other commands.
2
+// This example runs "type" against every key in the database
3
+//
4
+var client = require("redis").createClient();
5
+
6
+client.keys("*", function (err, keys) {
7
+    keys.forEach(function (key, pos) {
8
+        client.type(key, function (err, keytype) {
9
+            console.log(key + " is " + keytype);
10
+            if (pos === (keys.length - 1)) {
11
+                client.quit();
12
+            }
13
+        });
14
+    });
15
+});

+ 19
- 0
node_modules/socket.io/node_modules/redis/examples/subquery.js View File

@@ -0,0 +1,19 @@
1
+var client = require("redis").createClient();
2
+
3
+function print_results(obj) {
4
+    console.dir(obj);
5
+}
6
+
7
+// build a map of all keys and their types
8
+client.keys("*", function (err, all_keys) {
9
+    var key_types = {};
10
+    
11
+    all_keys.forEach(function (key, pos) { // use second arg of forEach to get pos
12
+        client.type(key, function (err, type) {
13
+            key_types[key] = type;
14
+            if (pos === all_keys.length - 1) { // callbacks all run in order
15
+                print_results(key_types);
16
+            }
17
+        });
18
+    });
19
+});

+ 29
- 0
node_modules/socket.io/node_modules/redis/examples/unix_socket.js View File

@@ -0,0 +1,29 @@
1
+var redis = require("redis"),
2
+    client = redis.createClient("/tmp/redis.sock"),
3
+    profiler = require("v8-profiler");
4
+
5
+client.on("connect", function () {
6
+    console.log("Got Unix socket connection.")
7
+});
8
+
9
+client.on("error", function (err) {
10
+    console.log(err.message);
11
+});
12
+
13
+client.set("space chars", "space value");
14
+
15
+setInterval(function () {
16
+    client.get("space chars");
17
+}, 100);
18
+
19
+function done() {
20
+    client.info(function (err, reply) {
21
+        console.log(reply.toString());
22
+        client.quit();
23
+    });
24
+}
25
+
26
+setTimeout(function () {
27
+    console.log("Taking snapshot.");
28
+    var snap = profiler.takeSnapshot();
29
+}, 5000);

+ 31
- 0
node_modules/socket.io/node_modules/redis/examples/web_server.js View File

@@ -0,0 +1,31 @@
1
+// A simple web server that generates dyanmic content based on responses from Redis
2
+
3
+var http = require("http"), server,
4
+    redis_client = require("redis").createClient();
5
+
6
+server = http.createServer(function (request, response) {
7
+    response.writeHead(200, {
8
+        "Content-Type": "text/plain"
9
+    });
10
+    
11
+    var redis_info, total_requests;
12
+    
13
+    redis_client.info(function (err, reply) {
14
+        redis_info = reply; // stash response in outer scope
15
+    });
16
+    redis_client.incr("requests", function (err, reply) {
17
+        total_requests = reply; // stash response in outer scope
18
+    });
19
+    redis_client.hincrby("ip", request.connection.remoteAddress, 1);
20
+    redis_client.hgetall("ip", function (err, reply) {
21
+        // This is the last reply, so all of the previous replies must have completed already
22
+        response.write("This page was generated after talking to redis.\n\n" +
23
+            "Redis info:\n" + redis_info + "\n" +
24
+            "Total requests: " + total_requests + "\n\n" +
25
+            "IP count: \n");
26
+        Object.keys(reply).forEach(function (ip) {
27
+            response.write("    " + ip + ": " + reply[ip] + "\n");
28
+        });
29
+        response.end();
30
+    });
31
+}).listen(80);

+ 39
- 0
node_modules/socket.io/node_modules/redis/generate_commands.js View File

@@ -0,0 +1,39 @@
1
+var http = require("http"),
2
+    fs = require("fs");
3
+
4
+function prettyCurrentTime() {
5
+    var date = new Date();
6
+    return date.toLocaleString();
7
+}
8
+
9
+function write_file(commands, path) {
10
+    var file_contents, out_commands;
11
+
12
+    console.log("Writing " + Object.keys(commands).length + " commands to " + path);
13
+
14
+    file_contents = "// This file was generated by ./generate_commands.js on " + prettyCurrentTime() + "\n";
15
+
16
+    out_commands = Object.keys(commands).map(function (key) {
17
+        return key.toLowerCase();
18
+    });
19
+
20
+    file_contents += "module.exports = " + JSON.stringify(out_commands, null, "    ") + ";\n";
21
+
22
+    fs.writeFile(path, file_contents);
23
+}
24
+
25
+http.get({host: "redis.io", path: "/commands.json"}, function (res) {
26
+    var body = "";
27
+
28
+    console.log("Response from redis.io/commands.json: " + res.statusCode);
29
+
30
+    res.on('data', function (chunk) {
31
+        body += chunk;
32
+    });
33
+
34
+    res.on('end', function () {
35
+        write_file(JSON.parse(body), "lib/commands.js");
36
+    });
37
+}).on('error', function (e) {
38
+    console.log("Error fetching command list from redis.io: " + e.message);
39
+});

+ 1113
- 0
node_modules/socket.io/node_modules/redis/index.js
File diff suppressed because it is too large
View File


+ 147
- 0
node_modules/socket.io/node_modules/redis/lib/commands.js View File

@@ -0,0 +1,147 @@
1
+// This file was generated by ./generate_commands.js on Mon Aug 06 2012 15:04:06 GMT-0700 (PDT)
2
+module.exports = [
3
+    "append",
4
+    "auth",
5
+    "bgrewriteaof",
6
+    "bgsave",
7
+    "bitcount",
8
+    "bitop",
9
+    "blpop",
10
+    "brpop",
11
+    "brpoplpush",
12
+    "client kill",
13
+    "client list",
14
+    "config get",
15
+    "config set",
16
+    "config resetstat",
17
+    "dbsize",
18
+    "debug object",
19
+    "debug segfault",
20
+    "decr",
21
+    "decrby",
22
+    "del",
23
+    "discard",
24
+    "dump",
25
+    "echo",
26
+    "eval",
27
+    "evalsha",
28
+    "exec",
29
+    "exists",
30
+    "expire",
31
+    "expireat",
32
+    "flushall",
33
+    "flushdb",
34
+    "get",
35
+    "getbit",
36
+    "getrange",
37
+    "getset",
38
+    "hdel",
39
+    "hexists",
40
+    "hget",
41
+    "hgetall",
42
+    "hincrby",
43
+    "hincrbyfloat",
44
+    "hkeys",
45
+    "hlen",
46
+    "hmget",
47
+    "hmset",
48
+    "hset",
49
+    "hsetnx",
50
+    "hvals",
51
+    "incr",
52
+    "incrby",
53
+    "incrbyfloat",
54
+    "info",
55
+    "keys",
56
+    "lastsave",
57
+    "lindex",
58
+    "linsert",
59
+    "llen",
60
+    "lpop",
61
+    "lpush",
62
+    "lpushx",
63
+    "lrange",
64
+    "lrem",
65
+    "lset",
66
+    "ltrim",
67
+    "mget",
68
+    "migrate",
69
+    "monitor",
70
+    "move",
71
+    "mset",
72
+    "msetnx",
73
+    "multi",
74
+    "object",
75
+    "persist",
76
+    "pexpire",
77
+    "pexpireat",
78
+    "ping",
79
+    "psetex",
80
+    "psubscribe",
81
+    "pttl",
82
+    "publish",
83
+    "punsubscribe",
84
+    "quit",
85
+    "randomkey",
86
+    "rename",
87
+    "renamenx",
88
+    "restore",
89
+    "rpop",
90
+    "rpoplpush",
91
+    "rpush",
92
+    "rpushx",
93
+    "sadd",
94
+    "save",
95
+    "scard",
96
+    "script exists",
97
+    "script flush",
98
+    "script kill",
99
+    "script load",
100
+    "sdiff",
101
+    "sdiffstore",
102
+    "select",
103
+    "set",
104
+    "setbit",
105
+    "setex",
106
+    "setnx",
107
+    "setrange",
108
+    "shutdown",
109
+    "sinter",
110
+    "sinterstore",
111
+    "sismember",
112
+    "slaveof",
113
+    "slowlog",
114
+    "smembers",
115
+    "smove",
116
+    "sort",
117
+    "spop",
118
+    "srandmember",
119
+    "srem",
120
+    "strlen",
121
+    "subscribe",
122
+    "sunion",
123
+    "sunionstore",
124
+    "sync",
125
+    "time",
126
+    "ttl",
127
+    "type",
128
+    "unsubscribe",
129
+    "unwatch",
130
+    "watch",
131
+    "zadd",
132
+    "zcard",
133
+    "zcount",
134
+    "zincrby",
135
+    "zinterstore",
136
+    "zrange",
137
+    "zrangebyscore",
138
+    "zrank",
139
+    "zrem",
140
+    "zremrangebyrank",
141
+    "zremrangebyscore",
142
+    "zrevrange",
143
+    "zrevrangebyscore",
144
+    "zrevrank",
145
+    "zscore",
146
+    "zunionstore"
147
+];

+ 46
- 0
node_modules/socket.io/node_modules/redis/lib/parser/hiredis.js View File

@@ -0,0 +1,46 @@
1
+/*global Buffer require exports console setTimeout */
2
+
3
+var events = require("events"),
4
+    util = require("../util"),
5
+    hiredis = require("hiredis");
6
+
7
+exports.debug_mode = false;
8
+exports.name = "hiredis";
9
+
10
+function HiredisReplyParser(options) {
11
+    this.name = exports.name;
12
+    this.options = options || {};
13
+    this.reset();
14
+    events.EventEmitter.call(this);
15
+}
16
+
17
+util.inherits(HiredisReplyParser, events.EventEmitter);
18
+
19
+exports.Parser = HiredisReplyParser;
20
+
21
+HiredisReplyParser.prototype.reset = function () {
22
+    this.reader = new hiredis.Reader({
23
+        return_buffers: this.options.return_buffers || false
24
+    });
25
+};
26
+
27
+HiredisReplyParser.prototype.execute = function (data) {
28
+    var reply;
29
+    this.reader.feed(data);
30
+    while (true) {
31
+        try {
32
+          reply = this.reader.get();
33
+        } catch (err) {
34
+          this.emit("error", err);
35
+          break;
36
+        }
37
+
38
+        if (reply === undefined) break;
39
+
40
+        if (reply && reply.constructor === Error) {
41
+            this.emit("reply error", reply);
42
+        } else {
43
+            this.emit("reply", reply);
44
+        }
45
+    }
46
+};

+ 317
- 0
node_modules/socket.io/node_modules/redis/lib/parser/javascript.js View File

@@ -0,0 +1,317 @@
1
+/*global Buffer require exports console setTimeout */
2
+
3
+// TODO - incorporate these V8 pro tips:
4
+//    pre-allocate Arrays if length is known in advance
5
+//    do not use delete
6
+//    use numbers for parser state
7
+
8
+var events = require("events"),
9
+    util = require("../util");
10
+
11
+exports.debug_mode = false;
12
+exports.name = "javascript";
13
+
14
+function RedisReplyParser(options) {
15
+    this.name = exports.name;
16
+    this.options = options || {};
17
+    this.reset();
18
+    events.EventEmitter.call(this);
19
+}
20
+
21
+util.inherits(RedisReplyParser, events.EventEmitter);
22
+
23
+exports.Parser = RedisReplyParser;
24
+
25
+// Buffer.toString() is quite slow for small strings
26
+function small_toString(buf, len) {
27
+    var tmp = "", i;
28
+
29
+    for (i = 0; i < len; i += 1) {
30
+        tmp += String.fromCharCode(buf[i]);
31
+    }
32
+
33
+    return tmp;
34
+}
35
+
36
+// Reset parser to it's original state.
37
+RedisReplyParser.prototype.reset = function () {
38
+    this.return_buffer = new Buffer(16384); // for holding replies, might grow
39
+    this.return_string = "";
40
+    this.tmp_string = ""; // for holding size fields
41
+
42
+    this.multi_bulk_length = 0;
43
+    this.multi_bulk_replies = null;
44
+    this.multi_bulk_pos = 0;
45
+    this.multi_bulk_nested_length = 0;
46
+    this.multi_bulk_nested_replies = null;
47
+
48
+    this.states = {
49
+        TYPE: 1,
50
+        SINGLE_LINE: 2,
51
+        MULTI_BULK_COUNT: 3,
52
+        INTEGER_LINE: 4,
53
+        BULK_LENGTH: 5,
54
+        ERROR_LINE: 6,
55
+        BULK_DATA: 7,
56
+        UNKNOWN_TYPE: 8,
57
+        FINAL_CR: 9,
58
+        FINAL_LF: 10,
59
+        MULTI_BULK_COUNT_LF: 11,
60
+        BULK_LF: 12
61
+    };
62
+    
63
+    this.state = this.states.TYPE;
64
+};
65
+
66
+RedisReplyParser.prototype.parser_error = function (message) {
67
+    this.emit("error", message);
68
+    this.reset();
69
+};
70
+
71
+RedisReplyParser.prototype.execute = function (incoming_buf) {
72
+    var pos = 0, bd_tmp, bd_str, i, il, states = this.states;
73
+    //, state_times = {}, start_execute = new Date(), start_switch, end_switch, old_state;
74
+    //start_switch = new Date();
75
+
76
+    while (pos < incoming_buf.length) {
77
+        // old_state = this.state;
78
+        // console.log("execute: " + this.state + ", " + pos + "/" + incoming_buf.length + ", " + String.fromCharCode(incoming_buf[pos]));
79
+
80
+        switch (this.state) {
81
+        case 1: // states.TYPE
82
+            this.type = incoming_buf[pos];
83
+            pos += 1;
84
+
85
+            switch (this.type) {
86
+            case 43: // +
87
+                this.state = states.SINGLE_LINE;
88
+                this.return_buffer.end = 0;
89
+                this.return_string = "";
90
+                break;
91
+            case 42: // *
92
+                this.state = states.MULTI_BULK_COUNT;
93
+                this.tmp_string = "";
94
+                break;
95
+            case 58: // :
96
+                this.state = states.INTEGER_LINE;
97
+                this.return_buffer.end = 0;
98
+                this.return_string = "";
99
+                break;
100
+            case 36: // $
101
+                this.state = states.BULK_LENGTH;
102
+                this.tmp_string = "";
103
+                break;
104
+            case 45: // -
105
+                this.state = states.ERROR_LINE;
106
+                this.return_buffer.end = 0;
107
+                this.return_string = "";
108
+                break;
109
+            default:
110
+                this.state = states.UNKNOWN_TYPE;
111
+            }
112
+            break;
113
+        case 4: // states.INTEGER_LINE
114
+            if (incoming_buf[pos] === 13) {
115
+                this.send_reply(+small_toString(this.return_buffer, this.return_buffer.end));
116
+                this.state = states.FINAL_LF;
117
+            } else {
118
+                this.return_buffer[this.return_buffer.end] = incoming_buf[pos];
119
+                this.return_buffer.end += 1;
120
+            }
121
+            pos += 1;
122
+            break;
123
+        case 6: // states.ERROR_LINE
124
+            if (incoming_buf[pos] === 13) {
125
+                this.send_error(this.return_buffer.toString("ascii", 0, this.return_buffer.end));
126
+                this.state = states.FINAL_LF;
127
+            } else {
128
+                this.return_buffer[this.return_buffer.end] = incoming_buf[pos];
129
+                this.return_buffer.end += 1;
130
+            }
131
+            pos += 1;
132
+            break;
133
+        case 2: // states.SINGLE_LINE
134
+            if (incoming_buf[pos] === 13) {
135
+                this.send_reply(this.return_string);
136
+                this.state = states.FINAL_LF;
137
+            } else {
138
+                this.return_string += String.fromCharCode(incoming_buf[pos]);
139
+            }
140
+            pos += 1;
141
+            break;
142
+        case 3: // states.MULTI_BULK_COUNT
143
+            if (incoming_buf[pos] === 13) { // \r
144
+                this.state = states.MULTI_BULK_COUNT_LF;
145
+            } else {
146
+                this.tmp_string += String.fromCharCode(incoming_buf[pos]);
147
+            }
148
+            pos += 1;
149
+            break;
150
+        case 11: // states.MULTI_BULK_COUNT_LF
151
+            if (incoming_buf[pos] === 10) { // \n
152
+                if (this.multi_bulk_length) { // nested multi-bulk
153
+                    this.multi_bulk_nested_length = this.multi_bulk_length;
154
+                    this.multi_bulk_nested_replies = this.multi_bulk_replies;
155
+                    this.multi_bulk_nested_pos = this.multi_bulk_pos;
156
+                }
157
+                this.multi_bulk_length = +this.tmp_string;
158
+                this.multi_bulk_pos = 0;
159
+                this.state = states.TYPE;
160
+                if (this.multi_bulk_length < 0) {
161
+                    this.send_reply(null);
162
+                    this.multi_bulk_length = 0;
163
+                } else if (this.multi_bulk_length === 0) {
164
+                    this.multi_bulk_pos = 0;
165
+                    this.multi_bulk_replies = null;
166
+                    this.send_reply([]);
167
+                } else {
168
+                    this.multi_bulk_replies = new Array(this.multi_bulk_length);
169
+                }
170
+            } else {
171
+                this.parser_error(new Error("didn't see LF after NL reading multi bulk count"));
172
+                return;
173
+            }
174
+            pos += 1;
175
+            break;
176
+        case 5: // states.BULK_LENGTH
177
+            if (incoming_buf[pos] === 13) { // \r
178
+                this.state = states.BULK_LF;
179
+            } else {
180
+                this.tmp_string += String.fromCharCode(incoming_buf[pos]);
181
+            }
182
+            pos += 1;
183
+            break;
184
+        case 12: // states.BULK_LF
185
+            if (incoming_buf[pos] === 10) { // \n
186
+                this.bulk_length = +this.tmp_string;
187
+                if (this.bulk_length === -1) {
188
+                    this.send_reply(null);
189
+                    this.state = states.TYPE;
190
+                } else if (this.bulk_length === 0) {
191
+                    this.send_reply(new Buffer(""));
192
+                    this.state = states.FINAL_CR;
193
+                } else {
194
+                    this.state = states.BULK_DATA;
195
+                    if (this.bulk_length > this.return_buffer.length) {
196
+                        if (exports.debug_mode) {
197
+                            console.log("Growing return_buffer from " + this.return_buffer.length + " to " + this.bulk_length);
198
+                        }
199
+                        this.return_buffer = new Buffer(this.bulk_length);
200
+                    }
201
+                    this.return_buffer.end = 0;
202
+                }
203
+            } else {
204
+                this.parser_error(new Error("didn't see LF after NL while reading bulk length"));
205
+                return;
206
+            }
207
+            pos += 1;
208
+            break;
209
+        case 7: // states.BULK_DATA
210
+            this.return_buffer[this.return_buffer.end] = incoming_buf[pos];
211
+            this.return_buffer.end += 1;
212
+            pos += 1;
213
+            if (this.return_buffer.end === this.bulk_length) {
214
+                bd_tmp = new Buffer(this.bulk_length);
215
+                // When the response is small, Buffer.copy() is a lot slower.
216
+                if (this.bulk_length > 10) {
217
+                    this.return_buffer.copy(bd_tmp, 0, 0, this.bulk_length);
218
+                } else {
219
+                    for (i = 0, il = this.bulk_length; i < il; i += 1) {
220
+                        bd_tmp[i] = this.return_buffer[i];
221
+                    }
222
+                }
223
+                this.send_reply(bd_tmp);
224
+                this.state = states.FINAL_CR;
225
+            }
226
+            break;
227
+        case 9: // states.FINAL_CR
228
+            if (incoming_buf[pos] === 13) { // \r
229
+                this.state = states.FINAL_LF;
230
+                pos += 1;
231
+            } else {
232
+                this.parser_error(new Error("saw " + incoming_buf[pos] + " when expecting final CR"));
233
+                return;
234
+            }
235
+            break;
236
+        case 10: // states.FINAL_LF
237
+            if (incoming_buf[pos] === 10) { // \n
238
+                this.state = states.TYPE;
239
+                pos += 1;
240
+            } else {
241
+                this.parser_error(new Error("saw " + incoming_buf[pos] + " when expecting final LF"));
242
+                return;
243
+            }
244
+            break;
245
+        default:
246
+            this.parser_error(new Error("invalid state " + this.state));
247
+        }
248
+        // end_switch = new Date();
249
+        // if (state_times[old_state] === undefined) {
250
+        //     state_times[old_state] = 0;
251
+        // }
252
+        // state_times[old_state] += (end_switch - start_switch);
253
+        // start_switch = end_switch;
254
+    }
255
+    // console.log("execute ran for " + (Date.now() - start_execute) + " ms, on " + incoming_buf.length + " Bytes. ");
256
+    // Object.keys(state_times).forEach(function (state) {
257
+    //     console.log("    " + state + ": " + state_times[state]);
258
+    // });
259
+};
260
+
261
+RedisReplyParser.prototype.send_error = function (reply) {
262
+    if (this.multi_bulk_length > 0 || this.multi_bulk_nested_length > 0) {
263
+        // TODO - can this happen?  Seems like maybe not.
264
+        this.add_multi_bulk_reply(reply);
265
+    } else {
266
+        this.emit("reply error", reply);
267
+    }
268
+};
269
+
270
+RedisReplyParser.prototype.send_reply = function (reply) {
271
+    if (this.multi_bulk_length > 0 || this.multi_bulk_nested_length > 0) {
272
+        if (!this.options.return_buffers && Buffer.isBuffer(reply)) {
273
+            this.add_multi_bulk_reply(reply.toString("utf8"));
274
+        } else {
275
+            this.add_multi_bulk_reply(reply);
276
+        }
277
+    } else {
278
+        if (!this.options.return_buffers && Buffer.isBuffer(reply)) {
279
+            this.emit("reply", reply.toString("utf8"));
280
+        } else {
281
+            this.emit("reply", reply);
282
+        }
283
+    }
284
+};
285
+
286
+RedisReplyParser.prototype.add_multi_bulk_reply = function (reply) {
287
+    if (this.multi_bulk_replies) {
288
+        this.multi_bulk_replies[this.multi_bulk_pos] = reply;
289
+        this.multi_bulk_pos += 1;
290
+        if (this.multi_bulk_pos < this.multi_bulk_length) {
291
+            return;
292
+        }
293
+    } else {
294
+        this.multi_bulk_replies = reply;
295
+    }
296
+
297
+    if (this.multi_bulk_nested_length > 0) {
298
+        this.multi_bulk_nested_replies[this.multi_bulk_nested_pos] = this.multi_bulk_replies;
299
+        this.multi_bulk_nested_pos += 1;
300
+
301
+        this.multi_bulk_length = 0;
302
+        this.multi_bulk_replies = null;
303
+        this.multi_bulk_pos = 0;
304
+
305
+        if (this.multi_bulk_nested_length === this.multi_bulk_nested_pos) {
306
+            this.emit("reply", this.multi_bulk_nested_replies);
307
+            this.multi_bulk_nested_length = 0;
308
+            this.multi_bulk_nested_pos = 0;
309
+            this.multi_bulk_nested_replies = null;
310
+        }
311
+    } else {
312
+        this.emit("reply", this.multi_bulk_replies);
313
+        this.multi_bulk_length = 0;
314
+        this.multi_bulk_replies = null;
315
+        this.multi_bulk_pos = 0;
316
+    }
317
+};

+ 61
- 0
node_modules/socket.io/node_modules/redis/lib/queue.js View File

@@ -0,0 +1,61 @@
1
+var to_array = require("./to_array");
2
+
3
+// Queue class adapted from Tim Caswell's pattern library
4
+// http://github.com/creationix/pattern/blob/master/lib/pattern/queue.js
5
+
6
+function Queue() {
7
+    this.tail = [];
8
+    this.head = [];
9
+    this.offset = 0;
10
+}
11
+
12
+Queue.prototype.shift = function () {
13
+    if (this.offset === this.head.length) {
14
+        var tmp = this.head;
15
+        tmp.length = 0;
16
+        this.head = this.tail;
17
+        this.tail = tmp;
18
+        this.offset = 0;
19
+        if (this.head.length === 0) {
20
+            return;
21
+        }
22
+    }
23
+    return this.head[this.offset++]; // sorry, JSLint
24
+};
25
+
26
+Queue.prototype.push = function (item) {
27
+    return this.tail.push(item);
28
+};
29
+
30
+Queue.prototype.forEach = function (fn, thisv) {
31
+    var array = this.head.slice(this.offset), i, il;
32
+
33
+    array.push.apply(array, this.tail);
34
+
35
+    if (thisv) {
36
+        for (i = 0, il = array.length; i < il; i += 1) {
37
+            fn.call(thisv, array[i], i, array);
38
+        }
39
+    } else {
40
+        for (i = 0, il = array.length; i < il; i += 1) {
41
+            fn(array[i], i, array);
42
+        }
43
+    }
44
+
45
+    return array;
46
+};
47
+
48
+Queue.prototype.getLength = function () {
49
+    return this.head.length - this.offset + this.tail.length;
50
+};
51
+    
52
+Object.defineProperty(Queue.prototype, 'length', {
53
+    get: function () {
54
+        return this.getLength();
55
+    }
56
+});
57
+
58
+
59
+if(typeof module !== 'undefined' && module.exports) {
60
+  module.exports = Queue;
61
+}

+ 12
- 0
node_modules/socket.io/node_modules/redis/lib/to_array.js View File

@@ -0,0 +1,12 @@
1
+function to_array(args) {
2
+    var len = args.length,
3
+        arr = new Array(len), i;
4
+
5
+    for (i = 0; i < len; i += 1) {
6
+        arr[i] = args[i];
7
+    }
8
+
9
+    return arr;
10
+}
11
+
12
+module.exports = to_array;

+ 11
- 0
node_modules/socket.io/node_modules/redis/lib/util.js View File

@@ -0,0 +1,11 @@
1
+// Support for very old versions of node where the module was called "sys".  At some point, we should abandon this.
2
+
3
+var util;
4
+
5
+try {
6
+    util = require("util");
7
+} catch (err) {
8
+    util = require("sys");
9
+}
10
+
11
+module.exports = util;

+ 11
- 0
node_modules/socket.io/node_modules/redis/mem.js View File

@@ -0,0 +1,11 @@
1
+var client = require("redis").createClient();
2
+
3
+client.set("foo", "barvalskdjlksdjflkdsjflksdjdflkdsjflksdjflksdj", function (err, res) {
4
+    if (err) {
5
+        console.log("Got an error, please adapt somehow.");
6
+    } else {
7
+        console.log("Got a result: " + res);
8
+    }
9
+});
10
+
11
+client.quit();

+ 0
- 0
node_modules/socket.io/node_modules/redis/multi_bench.js View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save