Compare commits

...

178 Commits

Author SHA1 Message Date
Guillermo Rauch
3b7224c7e0 Release 0.9.11 2012-11-02 08:03:15 -07:00
Guillermo Rauch
2030cf1432 package: move redis to optionalDependenices [3rd-Eden] 2012-11-02 08:01:24 -07:00
Guillermo Rauch
de9e8dffe1 Release 0.9.10 2012-08-10 13:34:50 -07:00
Guillermo Rauch
3a3044ebba Merge pull request #972 from Coreh/express-3.x-readme
Add express 3.0 instructions on Readme.md
2012-08-10 10:17:55 -07:00
Guillermo Rauch
d10b4dd1bd Merge pull request #985 from GICodeWarrior/log-case-fix
Don't lowercase log messages
2012-08-08 18:03:57 -07:00
Rusty Burchfield
12beee2d63 Don't lowercase log messages
Lowercasing log messages is unnecessary.  It makes some messages difficult to
read, and others difficult to search for.
2012-08-08 11:32:57 -07:00
Guillermo Rauch
875f14d16b Revert "Fix infinite recursion in Websocket parsers."
This reverts commit c218468f67.
2012-08-07 13:18:41 -07:00
Guillermo Rauch
8ca8990a0c Merge pull request #983 from GICodeWarrior/parser-recursion
Fix infinite recursion in Websocket parsers.
2012-08-06 13:16:37 -07:00
Rusty Burchfield
c218468f67 Fix infinite recursion in Websocket parsers.
If a client is feeding messages faster than server can handle them, infinite
recursion occurs.  Basically, the "overflow" data gets added to the parser and
it immediately parses a new message.

The fix pushes the processing of the next message (in this edge case) onto the
event queue.  This prevents the stack from recursing indefinitely.  This also
prevents a fast client from starving other clients.
2012-08-06 13:03:51 -07:00
Guillermo Rauch
4164e3bd7e Merge pull request #981 from doozr/honour-flash-settings
Honour flash settings
2012-08-06 08:59:17 -07:00
Guillermo Rauch
46227e7ac9 Merge pull request #980 from doozr/jsonp-error-crash
Always set the HTTP response in case an error should be returned to the client
2012-08-06 08:58:57 -07:00
Craig Andrews
d723d363b2 Always set the HTTP response in case an error should be returned to the client 2012-08-06 14:16:06 +01:00
Craig Andrews
fa1c1b2ada Create or destroy the flash policy server on configuration change 2012-08-06 14:14:15 +01:00
Craig Andrews
d32a848c3f Honour configuration to disable flash policy server 2012-08-06 14:14:14 +01:00
Guillermo Rauch
48ad0d3d1d Release 0.9.9 2012-08-01 15:14:02 -07:00
Guillermo Rauch
281a467960 manager: added response to sync disconnect xhrs 2012-08-01 15:08:06 -07:00
Guillermo Rauch
1fa74a46a3 Revert "Fix disconnectSync getting ignored"
This reverts commit f48b40e134.
2012-08-01 11:58:28 -07:00
Guillermo Rauch
ca4e3f32a3 Merge pull request #975 from huancz/master
fix issue #961 - restore compatibility with earlier node releases (up to 0.4.x)
2012-07-31 08:34:22 -07:00
Guillermo Rauch
9dd8134e6a Merge pull request #970 from renier/master
Codebase needs a license file (#965)
2012-07-31 08:32:07 -07:00
Renier Morales
180f1c91b9 Put license text in its own file (#965) 2012-07-31 11:07:21 -04:00
Marco Aurélio
bddf652c25 Add express 3.0 instructions on Readme.md 2012-07-30 15:53:47 -03:00
Guillermo Rauch
c795e4cf1a Merge pull request #971 from Coreh/express-3.x-warn
Add warning to .listen() to ease the migration to Express 3.x
2012-07-30 11:49:53 -07:00
Marco Aurélio
6afbb34581 Add warning to .listen() to ease the migration to Express 3.x 2012-07-30 15:43:00 -03:00
Guillermo Rauch
ac39dbc721 Merge pull request #964 from crickeys/xhr_polling_disconnectSync
Fix disconnectSync getting ignored
2012-07-27 10:06:03 -07:00
Petr Běhan
a5c5c20438 restore compatibility with node 0.4.x 2012-07-27 15:38:57 +02:00
Brian Gruber
f48b40e134 Fix disconnectSync getting ignored
If using xhr-polling and a browser closes a tab or window, the
disconnectSync in the socket.io-client method is called which sends an
XHR request to the server indicating a disconnect. This line would cause
that to be ignored and so the server would have to wait for a timeout to
mark them as disconnect. This was possibly because it was sent from a
different tcp socket than the current connection.
2012-07-26 21:19:00 -05:00
Guillermo Rauch
1679fd564c Release 0.9.8 2012-07-24 17:36:30 -07:00
Guillermo Rauch
bb900d445a Release 0.9.7 2012-07-24 11:16:20 -07:00
Guillermo Rauch
c6fed55f53 tests: fixed tests for 0.8 2012-07-24 10:39:23 -07:00
Guillermo Rauch
6adebc85fc Merge pull request #958 from xaroth8088/master
Prevent crash when socket leaves a room twice.
2012-07-22 11:26:21 -07:00
xaroth8088
7a087bcc94 Prevent crash when socket leaves a room twice. 2012-07-22 11:09:06 -07:00
Guillermo Rauch
18422183c8 Merge pull request #957 from xaroth8088/master
Corrects unsafe usage of for..in, permitting socket.io to be used in environments that extend Object, etc.
2012-07-21 11:44:28 -07:00
xaroth8088
aeb904f58b Corrects unsafe usage of for..in, permitting socket.io to be used in environments where Object, Function, etc. have been extended.
http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
2012-07-21 11:30:15 -07:00
xaroth8088
9c0b9de7f0 Revert "Corrects unsafe usage of for..in, permitting socket.io to be used in environments that extend Object, etc."
This reverts commit 81552c11ca.
2012-07-21 11:21:11 -07:00
xaroth8088
81552c11ca Corrects unsafe usage of for..in, permitting socket.io to be used in environments that extend Object, etc.
http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
2012-07-21 10:29:20 -07:00
Guillermo Rauch
e1fe76aebe Fix for node 0.8 with gzip compression. Thanks @vadimi 2012-07-09 16:58:02 -07:00
Guillermo Rauch
8197a0c854 Merge pull request #929 from sjonnet19/patch-1
Update redis to support Node 0.8.x
2012-06-26 06:29:08 -07:00
Shawn Jonnet
2b91f1407f Update redis to support Node 0.8.x 2012-06-25 23:30:24 -03:00
Guillermo Rauch
3b9715e8e7 Merge pull request #869 from MrSwitch/master
Small change to demo copy
2012-05-03 06:24:15 -07:00
Andrew Dodson
4e13cfb03e Update copy 2012-05-03 12:16:01 +10:00
Guillermo Rauch
39671e81a5 Merge pull request #868 from bodash/patch-1
I continued to have websocket connection issues in Safari when using SSL...
2012-05-02 12:21:24 -07:00
bodash
ffa8994a23 I continued to have websocket connection issues in Safari when using SSL that terminated at a load balancer. The shorthand logic that was here was nice and compact but didn't seem to work. Took the "intent" of the short hand and made it a bit more verbose and now it works. 2012-05-02 13:18:46 -06:00
Guillermo Rauch
de1afe1317 Merge pull request #857 from martinthomson/bug/856
Fix for ID generation vulnerability #856
2012-04-26 15:49:24 -07:00
Martin Thomson
aaad106b90 Adding node 0.4 backward compat for id gen 2012-04-26 15:08:19 -07:00
Martin Thomson
f850ddccd0 Removing more fixes for other bug 2012-04-26 14:35:17 -07:00
Martin Thomson
8d269aae4c Removing fixes for other bug 2012-04-26 14:33:37 -07:00
Martin Thomson
67b4eb9abd Making ID generation securely random 2012-04-26 14:28:00 -07:00
Guillermo Rauch
fe6dd87443 Merge pull request #848 from mbrevoort/redisStoreRaceCondition
Fix Redis Store race condition in manager onOpen unsubscribe callback
2012-04-23 15:30:30 -07:00
Mike Brevoort
d9aeaa494f Fix Redis Store race condition in manager onOpen unsubscribe callback 2012-04-23 16:06:31 -06:00
Guillermo Rauch
2024d45383 Merge pull request #841 from TooTallNate/master
fix for EventEmitters always reusing the same Array instance for listeners
2012-04-19 13:30:13 -07:00
Nathan Rajlich
e1884859bc fix for EventEmitters always reusing the same Array instance for listeners
This fixes node v0.7.x.

The node commits that broke this old behavior is here:
  78dc13fbf9%5E...928ea564d16da47e615ddac627e0b4d4a40d8196
2012-04-19 13:18:22 -07:00
Guillermo Rauch
0242a2ddf3 Merge branch 'master' of github.com:LearnBoost/socket.io 2012-04-17 19:51:49 -03:00
Guillermo Rauch
dbe6d5f740 Release 0.9.6 2012-04-17 19:51:37 -03:00
Guillermo Rauch
e98fc7bc86 Fixed XSS in jsonp-polling. 2012-04-17 19:48:32 -03:00
Guillermo Rauch
9bbf17f31e Merge pull request #827 from crickeys/patch-4
Fixes when browser doesn't send origin header, defaults to empty string ...
2012-04-11 15:02:50 -07:00
crickeys
1a5a87af13 Fixes when browser doesn't send origin header, defaults to empty string instead of UNDEFINED (which would throw an error on the origin.match(/^https/) below 2012-04-11 14:41:07 -05:00
Guillermo Rauch
a4e53a642b Release 0.9.5 2012-04-05 14:37:18 -03:00
Guillermo Rauch
6f36d8c2ff Added test for polling with connection close. 2012-04-05 14:32:10 -03:00
Guillermo Rauch
09fb16b443 Ensure close upon request close. 2012-04-05 14:31:50 -03:00
Guillermo Rauch
330407cc9d Fix disconnection reason being lost for polling transports. 2012-04-05 14:31:32 -03:00
Guillermo Rauch
2075307f23 Ensure that polling transports work with Connection: close 2012-04-05 14:31:13 -03:00
Guillermo Rauch
d7b06edaca Log disconnection reason 2012-04-05 14:31:01 -03:00
Guillermo Rauch
46fdcf00b3 Release 0.9.4 2012-04-01 01:50:50 -03:00
Guillermo Rauch
147b9bb941 Release 0.9.4 2012-04-01 01:49:51 -03:00
Guillermo Rauch
02a3da487c Merge branch 'master' of github.com:LearnBoost/socket.io 2012-04-01 01:48:25 -03:00
Guillermo Rauch
087c686ad0 Release 0.9.4 2012-04-01 01:48:13 -03:00
Guillermo Rauch
16205fc522 Merge pull request #809 from DanielBaulig/issue795-fix
Issue795 fix
2012-03-28 12:58:45 -07:00
Guillermo Rauch
a232159ce8 Release 0.9.3 2012-03-28 09:28:05 -03:00
Guillermo Rauch
b9c3255b7c Merge pull request #806 from mixu/upstream/fix-ff-xhr-post-syntax
Fix "syntax error" message on FF, resulting from FF trying to parse the POST result as XML due to it not having a response content-type
2012-03-27 16:54:29 -07:00
Mikito Takada
d80010dcf0 Firefox will try to parse the response from POST requests, causing a syntax error message in the Web Console. Basically an addition to https://github.com/LearnBoost/socket.io/pull/501 2012-03-27 16:43:17 -07:00
Daniel Baulig
00694a8a98 Fix issue #795 2012-03-19 22:03:31 +01:00
Daniel Baulig
da95094998 Add disconnect from namespace test-case for issue #795 2012-03-19 21:54:20 +01:00
Guillermo Rauch
e7d7582f84 Release 0.9.2 2012-03-13 11:00:50 -03:00
Guillermo Rauch
df5f23d309 More sensible close timeout default (fixes disconnect issue) 2012-03-13 10:49:06 -03:00
Guillermo Rauch
e018ba91eb Merge branch 'master' of github.com:LearnBoost/socket.io 2012-03-09 08:47:01 -03:00
Guillermo Rauch
c59aa6ff2c Getting ready for 1.0 2012-03-09 08:42:24 -03:00
Guillermo Rauch
9431709298 Merge pull request #787 from MatthewMueller/master
io.configure('development', function() {...}) will trigger if NODE_ENV is not defined.
2012-03-09 02:17:15 -08:00
Matt Mueller
a29525e043 NODE_ENV in configure now defaults to development, which is consistent with express 2012-03-09 02:10:58 -08:00
Guillermo Rauch
5312e154b3 Release 0.9.1-1 2012-03-02 08:41:17 -03:00
Guillermo Rauch
480b86f382 Bumped client with NPM dependency fix. 2012-03-02 08:40:41 -03:00
Guillermo Rauch
c0e2c3012f Release 0.9.1 2012-03-02 08:20:38 -03:00
Guillermo Rauch
97b04c4152 Merge branch 'master' of github.com:LearnBoost/socket.io 2012-03-02 07:50:59 -03:00
Guillermo Rauch
c8306e207d Temporarily removing node 0.4 from travis-ci 2012-02-29 11:01:11 -03:00
Guillermo Rauch
de5c0b3554 Merge pull request #771 from felixge/heartbeat
Make heartbeat timeout > heartbeat interval
2012-02-29 05:43:24 -08:00
Felix Geisendörfer
57a0b24060 Make heartbeat timeout > heartbeat interval
Otherwise clients would detect timeouts before a heartbeat has a chance
of reaching them. The new values themselves were suggested by @rauchg. I
myself think that the heartbeat timeout should probably only be ~10s larger
than the interval.
2012-02-29 14:15:37 +01:00
Guillermo Rauch
204576c006 Make these 2 tests work both on 0.4 and 0.6 2012-02-26 21:51:22 -03:00
Guillermo Rauch
66ac425bf7 Release 0.9.0 2012-02-26 21:46:39 -03:00
Guillermo Rauch
a01e7e2256 Make tests pass on 0.4 2012-02-26 18:21:25 -03:00
Guillermo Rauch
47cfa5aadf Fixed tests. All 250 passing. 2012-02-26 17:14:06 -03:00
Guillermo Rauch
ddd7f804af Fixed cross-domain xhr tests. 2012-02-26 17:11:52 -03:00
Guillermo Rauch
8c1c7a24ef Merge pull request #744 from ajaxorg/regexp-as-resource
make it possible to use a regexp to match the socket.io resource URL
2012-02-09 09:38:03 -08:00
Fabian Jakobs
09b130f4cf make it possible to use a regexp to match the
socket.io resource URL. We need this because we
have to prefix the socket.io URL with a variable
ID.
2012-02-09 17:17:55 +01:00
Guillermo Rauch
b662704b0b Merge pull request #737 from mixu/mixu/authfix2
Supplemental fix to gavinuhma/authfix, it looks like the same Access-Control-Origin logic is needed in the http and xhr-polling transports
2012-02-03 14:24:57 -08:00
Mikito Takada
304a4285ff Supplemental fix to gavinuhma/authfix, it looks like the same Access-Control-Origin logic is needed in the http and xhr-polling transports 2012-02-03 12:20:40 -08:00
Guillermo Rauch
6074795b19 Updated express dep for windows compatibility. 2012-01-11 07:41:09 -08:00
Guillermo Rauch
a139809a97 Updated express dep for windows compatibility. 2012-01-11 07:40:44 -08:00
Guillermo Rauch
8ff2edd79c Merge pull request #689 from bwillard/master
Improve performance of parser.decodePayload
2011-12-16 14:04:12 -08:00
Brian Willard
ebd25676ee combine two substr calls into one in decodePayload to improve performance 2011-12-16 15:31:48 -06:00
Guillermo Rauch
d9d529cb17 Merge pull request #683 from jherdman/documentation-fix
Minor documentation fix
2011-12-12 11:02:24 -08:00
James Herdman
b37666a8e8 Minor documentation fix 2011-12-12 11:10:25 -05:00
Guillermo Rauch
cc2270bb90 Merge pull request #622 from mattrobenolt/master
Location mismatch in Safari behind proxy
2011-12-05 14:04:57 -08:00
Matt Robenolt
36fc7b07ea Minor. Conform to style of other files. 2011-12-05 16:59:15 -05:00
Matt Robenolt
8eab3a87e7 Switching setting to 'match origin protocol' 2011-12-05 16:58:00 -05:00
Guillermo Rauch
94d513c85a Revert "Fixes leaking Redis subscriptions for #663. The local flag was not getting passed through onClientDisconnect()."
This reverts commit d5ab46d662.
2011-11-26 15:14:26 -08:00
Guillermo Rauch
70abe7aada Revert "Handle leaked dispatch:[id] subscription."
This reverts commit c110036f75.
2011-11-26 15:14:13 -08:00
Guillermo Rauch
9a8c1c4ae7 Merge pull request #667 from dshaw/patch/redis-disconnect
Patch/redis disconnect
2011-11-26 14:03:01 -08:00
Daniel Shaw
c110036f75 Handle leaked dispatch:[id] subscription. 2011-11-26 12:14:39 -08:00
Daniel Shaw
d5ab46d662 Fixes leaking Redis subscriptions for #663. The local flag was not getting passed through onClientDisconnect(). 2011-11-26 11:22:43 -08:00
Guillermo Rauch
eeaca6d9ac Merge pull request #662 from 3rd-Eden/leak
prevent memory leaking on uncompleted requests & add max post size limit...
2011-11-23 14:04:42 -08:00
Arnout Kazemier
a7f45fe6c0 prevent memory leaking on uncompleted requests & add max post size limitation 2011-11-23 22:28:38 +01:00
Guillermo Rauch
b59fd61d56 Merge pull request #661 from 3rd-Eden/travis
Fix for testcase
2011-11-22 14:52:36 -08:00
Arnout Kazemier
7948619609 Fix for testcase 2011-11-22 23:49:58 +01:00
Guillermo Rauch
6e8166d039 Merge pull request #660 from 3rd-Eden/travis
Assertvarnish
2011-11-22 14:43:21 -08:00
Arnout Kazemier
8fc3e37ca1 Merge branch 'master' of github.com:LearnBoost/socket.io into travis 2011-11-22 23:41:54 +01:00
Guillermo Rauch
17d0f4d489 Merge pull request #630 from gavinuhma/auth-fix
set Access-Control-Allow-Origin header to origin to enable withCredentials
2011-11-22 14:38:30 -08:00
Gavin Uhma
61e7e8955a Merge branch 'master' of git://github.com/LearnBoost/socket.io into auth-fix 2011-11-22 18:03:48 -04:00
Gavin Uhma
4c17f7f83b Set Access-Control-Allow-Credentials true, regardless of cookie 2011-11-22 18:03:25 -04:00
Arnout Kazemier
0f29d786b2 Remove assertvarnish from package as it breaks on 0.6 2011-11-22 21:18:15 +01:00
Guillermo Rauch
5ee6b43921 Merge pull request #659 from 3rd-Eden/travis
Added travis
2011-11-22 11:47:49 -08:00
Arnout Kazemier
f211f78019 Correct irc channel 2011-11-22 20:46:01 +01:00
Arnout Kazemier
eeb2a73f16 Added travis 2011-11-22 20:44:19 +01:00
Guillermo Rauch
3887633e35 Merge pull request #440 from dylang/master
Updated package.json to reflect new repo location
2011-11-16 13:05:31 -08:00
Guillermo Rauch
db8cf7673b Merge pull request #634 from christopherobin/master
Fixing issue #432
2011-11-16 13:05:18 -08:00
Guillermo Rauch
dfb852151b Merge pull request #570 from 3rd-Eden/logger
Use tty to detect if we should add colors or not by default.
2011-11-16 13:04:51 -08:00
Guillermo Rauch
7b6c85030e Merge pull request #643 from einaros/master
Bug fixes, and for some reason a heap of whitespace cleanups
2011-11-14 09:09:58 -08:00
einaros
2d5dcc1a8a whitespace cleanup 2011-11-14 17:57:34 +01:00
einaros
2b28c46400 added proper return after reserved field error 2011-11-14 17:50:57 +01:00
einaros
27714d7286 fixes manager.js failure to close connection after transport error has happened 2011-11-14 17:40:16 +01:00
einaros
ffef944dd5 added implicit port 80 for origin checks. fixes #638 2011-11-14 09:45:44 +01:00
Christophe Robin
f4b434a6a5 Fixed bug #432 in 0.8.7 2011-11-11 11:06:56 +09:00
Gavin Uhma
e4a9342e8b set Access-Control-Allow-Origin header to origin to enable withCredentials 2011-11-08 18:22:30 -04:00
Guillermo Rauch
3ed6b79781 Release 0.8.7 2011-11-05 13:50:53 -07:00
Matt Robenolt
6f2270add6 Adding configuration variable matchOriginProtocol
matchOriginProtocol is meant to be used when running socket.io behind a
proxy. matchOriginProtocol should be set to true when you want the
location handshake to match the protocol of the origin. This fixes
issues with terminating the SSL in front of Node and forcing location
to think it's wss instead of ws.
2011-11-03 15:34:24 -04:00
Matt Robenolt
220f8d5bf5 Fixes location mismatch error in Safari. 2011-11-03 01:35:18 -03:00
Guillermo Rauch
946418e70e Merge pull request #621 from einaros/master
Deals with a memleak in namespaces, and silently drops malformed websocket connections
2011-11-02 15:11:21 -07:00
Guillermo Rauch
2bb60ac40b Merge pull request #616 from thekiur/master
This patch will prevent some random memory leaking.
2011-11-02 11:25:19 -07:00
TJ Holowaychuk
e20777d21d Merge pull request #617 from sutiam/patch-2
add semicolon
2011-11-01 17:33:08 -07:00
sutiam
311ef7e7e7 add semicolon 2011-11-01 17:26:33 -07:00
thekiur
9e92075cbb Removed useless object: closedA, probably fixed a memory leak 2011-11-01 23:31:58 +02:00
einaros
63043b3d5d fixes leak #608 2011-10-31 22:47:25 +01:00
einaros
92a3cce272 circumvents #602 .. although only a horribly malformed websocket connection could potentially cause this 2011-10-28 14:04:55 +02:00
Guillermo Rauch
8339c96e84 Merge pull request #596 from einaros/nodenext
Node v0.5+ compatibility
2011-10-28 01:30:18 -07:00
einaros
a125fcb1a4 further updates to chat example dependencies 2011-10-28 10:18:47 +02:00
einaros
97f634f18f further updates to irc example dependencies 2011-10-28 10:18:08 +02:00
einaros
82266cf202 updated stylus dependency in examples to node 0.5+ compatible version 2011-10-28 10:14:26 +02:00
einaros
be94641651 fixed irc example for nodenext 2011-10-28 10:12:52 +02:00
einaros
703d1d778e fixed chat example for nodenext 2011-10-28 10:10:45 +02:00
einaros
70c61fa84d Merge remote branch 'upstream/master' into nodenext 2011-10-28 10:10:26 +02:00
einaros
3a07cc29bd added return for clarity 2011-10-26 08:21:22 +02:00
einaros
89a5134b66 corrected whitespace 2011-10-25 23:46:36 +02:00
einaros
6ca42fdc8f well thats five minutes of my life ill never get back. thanks. 2011-10-25 22:53:37 +02:00
einaros
a9f81a59c2 ensure backwards compatibility 2011-10-25 22:12:55 +02:00
einaros
8a90bf5234 re-enabled flashsocket tests, after bugfixes in flashsocket transport 2011-10-25 21:26:57 +02:00
einaros
357a9cb870 fixed race condition and scoping bug 2011-10-25 21:25:44 +02:00
einaros
8253ed573a ignore exception on port change 2011-10-25 19:47:39 +02:00
einaros
3f55d82bf7 added node v4 client closing compatibility 2011-10-25 13:30:06 +02:00
einaros
08467d4e12 temporarily disabled flash policy server tests 2011-10-25 13:19:39 +02:00
einaros
cb70f7873f moved default error handler 2011-10-25 13:18:40 +02:00
einaros
57b0ce73c7 resolve race condition 2011-10-25 13:09:04 +02:00
einaros
25f97431d4 set nodelay 2011-10-25 13:08:49 +02:00
einaros
f931af5758 fixed xhr-polling tests, in a way similar to jsonp 2011-10-25 10:45:20 +02:00
einaros
c88ea9ed61 fixed websocket testing, removed seemingly irrelevant tests 2011-10-25 10:42:18 +02:00
einaros
2bdee1b28f use new agent 2011-10-25 10:41:58 +02:00
einaros
a1f0b6c361 manager tests now pass properly 2011-10-24 21:26:15 +02:00
einaros
c1e64b90a4 added warning message from default error event handler 2011-10-23 23:03:23 +02:00
einaros
79c3d84a98 circumvent race condition due to changed http bits in 0.5 2011-10-23 14:21:22 +02:00
einaros
f6c376d087 another stab at proper 0.5 agent socket closing 2011-10-23 14:20:21 +02:00
einaros
bc15077ecc further checks to not close sockets that aren't there 2011-10-23 14:14:48 +02:00
einaros
28bf55e572 patched a few compatibility issues in node-websocket-server 2011-10-23 00:43:07 +02:00
einaros
f213d69e17 check that there's actually a socket to close 2011-10-22 14:39:59 +02:00
einaros
aa6f228ccf updated to use NODE_PATH rather than old expresso include argument 2011-10-22 14:39:33 +02:00
einaros
553b9e9d68 updated test to work with 0.5 2011-10-22 13:30:30 +02:00
einaros
ec6e43d7ee updated expresso dep 2011-10-22 13:30:12 +02:00
einaros
48140cf8a0 node 0.5 way of closing agent sockets 2011-10-22 13:29:57 +02:00
einaros
796bc9e95b capture error emitted by the server, which happens a lot with node 0.5+ 2011-10-22 13:28:54 +02:00
Arnout Kazemier
d9049f69c1 Merge branch 'master' of github.com:LearnBoost/socket.io into logger 2011-10-11 20:01:05 +02:00
Arnout Kazemier
10ffbd59e9 Use tty to detect if we should add colors or not by default. 2011-10-11 20:00:30 +02:00
Dylan Greene
a51fe07420 Updated the package location. 2011-08-01 14:44:11 -03:00
44 changed files with 1051 additions and 671 deletions

6
.travis.yml Normal file
View File

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

View File

@@ -1,4 +1,126 @@
0.9.11 / 2012-11-02
===================
* package: move redis to optionalDependenices [3rd-Eden]
* bumped client
0.9.10 / 2012-08-10
===================
* Don't lowercase log messages
* Always set the HTTP response in case an error should be returned to the client
* Create or destroy the flash policy server on configuration change
* Honour configuration to disable flash policy server
* Add express 3.0 instructions on Readme.md
* Bump client
0.9.9 / 2012-08-01
==================
* Fixed sync disconnect xhrs handling
* Put license text in its own file (#965)
* Add warning to .listen() to ease the migration to Express 3.x
* Restored compatibility with node 0.4.x
0.9.8 / 2012-07-24
==================
* Bumped client.
0.9.7 / 2012-07-24
==================
* Prevent crash when socket leaves a room twice.
* Corrects unsafe usage of for..in
* Fix for node 0.8 with `gzip compression` [vadimi]
* Update redis to support Node 0.8.x
* Made ID generation securely random
* Fix Redis Store race condition in manager onOpen unsubscribe callback
* Fix for EventEmitters always reusing the same Array instance for listeners
0.9.6 / 2012-04-17
==================
* Fixed XSS in jsonp-polling.
0.9.5 / 2012-04-05
==================
* Added test for polling and socket close.
* Ensure close upon request close.
* Fix disconnection reason being lost for polling transports.
* Ensure that polling transports work with Connection: close.
* Log disconnection reason.
0.9.4 / 2012-04-01
==================
* Disconnecting from namespace improvement (#795) [DanielBaulig]
* Bumped client with polling reconnection loop (#438)
0.9.3 / 2012-03-28
==================
* Fix "Syntax error" on FF Web Console with XHR Polling [mikito]
0.9.2 / 2012-03-13
==================
* More sensible close `timeout default` (fixes disconnect issue)
0.9.1-1 / 2012-03-02
====================
* Bumped client with NPM dependency fix.
0.9.1 / 2012-03-02
==================
* Changed heartbeat timeout and interval defaults (60 and 25 seconds)
* Make tests work both on 0.4 and 0.6
* Updated client (improvements + bug fixes).
0.9.0 / 2012-02-26
==================
* Make it possible to use a regexp to match the socket.io resource URL.
We need this because we have to prefix the socket.io URL with a variable ID.
* Supplemental fix to gavinuhma/authfix, it looks like the same Access-Control-Origin logic is needed in the http and xhr-polling transports
* Updated express dep for windows compatibility.
* Combine two substr calls into one in decodePayload to improve performance
* Minor documentation fix
* Minor. Conform to style of other files.
* Switching setting to 'match origin protocol'
* Revert "Fixes leaking Redis subscriptions for #663. The local flag was not getting passed through onClientDisconnect()."
* Revert "Handle leaked dispatch:[id] subscription."
* Merge pull request #667 from dshaw/patch/redis-disconnect
* Handle leaked dispatch:[id] subscription.
* Fixes leaking Redis subscriptions for #663. The local flag was not getting passed through onClientDisconnect().
* Prevent memory leaking on uncompleted requests & add max post size limitation
* Fix for testcase
* Set Access-Control-Allow-Credentials true, regardless of cookie
* Remove assertvarnish from package as it breaks on 0.6
* Correct irc channel
* Added proper return after reserved field error
* Fixes manager.js failure to close connection after transport error has happened
* Added implicit port 80 for origin checks. fixes #638
* Fixed bug #432 in 0.8.7
* Set Access-Control-Allow-Origin header to origin to enable withCredentials
* Adding configuration variable matchOriginProtocol
* Fixes location mismatch error in Safari.
* Use tty to detect if we should add colors or not by default.
* Updated the package location.
0.8.7 / 2011-11-05
==================
* Fixed memory leaks in closed clients.
* Fixed memory leaks in namespaces.
* Fixed websocket handling for malformed requests from proxies. [einaros]
* Node 0.6 compatibility. [einaros] [3rd-Eden]
* Adapted tests and examples.
0.8.6 / 2011-10-27
==================

22
LICENSE Normal file
View File

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

View File

@@ -6,13 +6,12 @@ run-tests:
@./node_modules/.bin/expresso \
-t 3000 \
-I support \
-I lib \
--serial \
$(TESTFLAGS) \
$(TESTS)
test:
@$(MAKE) TESTS="$(ALL_TESTS)" run-tests
@$(MAKE) NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests
test-cov:
@TESTFLAGS=--cov $(MAKE) test

View File

@@ -6,7 +6,9 @@ horizontal scalability, automatic JSON encoding/decoding, and more.
## How to Install
npm install socket.io
```bash
npm install socket.io
```
## How to use
@@ -19,6 +21,25 @@ var io = require('socket.io');
Next, attach it to a HTTP/HTTPS server. If you're using the fantastic `express`
web framework:
#### Express 3.x
```js
var app = express()
, server = require('http').createServer(app)
, io = io.listen(server);
server.listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
```
#### Express 2.x
```js
var app = express.createServer()
, io = io.listen(app);
@@ -102,10 +123,10 @@ io.sockets.on('connection', function (socket) {
var socket = io.connect('http://localhost');
socket.on('connect', function () {
socket.emit('set nickname', confirm('What is your nickname?'));
socket.emit('set nickname', prompt('What is your nickname?'));
socket.on('ready', function () {
console.log('Connected !');
socket.emit('msg', confirm('What is your message?'));
socket.emit('msg', prompt('What is your message?'));
});
});
</script>
@@ -131,7 +152,7 @@ The following example defines a socket that listens on '/chat' and one for
var io = require('socket.io').listen(80);
var chat = io
.of('/chat');
.of('/chat')
.on('connection', function (socket) {
socket.emit('a message', { that: 'only', '/chat': 'will get' });
chat.emit('a message', { everyone: 'in', '/chat': 'will get' });

View File

@@ -1,10 +1,3 @@
/**
* Bootstrap app.
*/
require.paths.unshift(__dirname + '/../../lib/');
/**
* Module dependencies.
*/
@@ -12,7 +5,7 @@ require.paths.unshift(__dirname + '/../../lib/');
var express = require('express')
, stylus = require('stylus')
, nib = require('nib')
, sio = require('socket.io');
, sio = require('../../lib/socket.io');
/**
* App.
@@ -25,7 +18,7 @@ var app = express.createServer();
*/
app.configure(function () {
app.use(stylus.middleware({ src: __dirname + '/public', compile: compile }))
app.use(stylus.middleware({ src: __dirname + '/public', compile: compile }));
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname);
app.set('view engine', 'jade');

View File

@@ -3,9 +3,9 @@
, "description": "example chat application with socket.io"
, "version": "0.0.1"
, "dependencies": {
"express": "2.3.11"
, "jade": "0.12.1"
, "stylus": "0.13.3"
, "nib": "0.0.8"
"express": "2.5.5"
, "jade": "0.16.4"
, "stylus": "0.19.0"
, "nib": "0.2.0"
}
}

View File

@@ -1,10 +1,3 @@
/**
* Bootstrap app.
*/
require.paths.unshift(__dirname + '/../../lib/');
/**
* Module dependencies.
*/
@@ -12,7 +5,7 @@ require.paths.unshift(__dirname + '/../../lib/');
var express = require('express')
, stylus = require('stylus')
, nib = require('nib')
, sio = require('socket.io')
, sio = require('../../lib/socket.io')
, irc = require('./irc');
/**

View File

@@ -2,7 +2,7 @@
* From https://github.com/felixge/nodelog/
*/
var sys = require('sys');
var sys = require('util');
var tcp = require('net');
var irc = exports;

View File

@@ -2,9 +2,9 @@
"name": "socket.io-irc"
, "version": "0.0.1"
, "dependencies": {
"express": "2.3.11"
, "jade": "0.12.1"
, "stylus": "0.13.3"
, "nib": "0.0.8"
"express": "2.5.5"
, "jade": "0.16.4"
, "stylus": "0.19.0"
, "nib": "0.2.0"
}
}

View File

@@ -10,6 +10,8 @@
var fs = require('fs')
, url = require('url')
, tty = require('tty')
, crypto = require('crypto')
, util = require('./util')
, store = require('./store')
, client = require('socket.io-client')
@@ -43,7 +45,8 @@ var defaultTransports = exports.defaultTransports = [
*/
var parent = module.parent.exports
, protocol = parent.protocol;
, protocol = parent.protocol
, jsonpolling_re = /^\d+$/;
/**
* Manager constructor.
@@ -69,14 +72,15 @@ function Manager (server, options) {
, authorization: false
, blacklist: ['disconnect']
, 'log level': 3
, 'log colors': true
, 'close timeout': 25
, 'heartbeat timeout': 15
, 'heartbeat interval': 20
, 'log colors': tty.isatty(process.stdout.fd)
, 'close timeout': 60
, 'heartbeat interval': 25
, 'heartbeat timeout': 60
, 'polling duration': 20
, 'flash policy server': true
, 'flash policy port': 10843
, 'destroy upgrade': true
, 'destroy buffer size': 10E7
, 'browser client': true
, 'browser client cache': true
, 'browser client minification': false
@@ -85,14 +89,22 @@ function Manager (server, options) {
, 'browser client gzip': false
, 'browser client handler': false
, 'client store expiration': 15
, 'match origin protocol': false
};
for (var i in options) {
this.settings[i] = options[i];
if (options.hasOwnProperty(i)) {
this.settings[i] = options[i];
}
}
var self = this;
// default error handler
server.on('error', function(err) {
self.log.warn('error raised: ' + err);
});
this.initStore();
this.on('set:store', function() {
@@ -100,8 +112,7 @@ function Manager (server, options) {
});
// reset listeners
this.oldListeners = server.listeners('request');
server.removeAllListeners('request');
this.oldListeners = server.listeners('request').splice(0);
server.on('request', function (req, res) {
self.handleRequest(req, res);
@@ -120,11 +131,21 @@ function Manager (server, options) {
});
for (var i in transports) {
if (transports[i].init) {
transports[i].init(this);
if (transports.hasOwnProperty(i)) {
if (transports[i].init) {
transports[i].init(this);
}
}
}
// forward-compatibility with 1.0
var self = this;
this.sockets.on('connection', function (conn) {
self.emit('connection', conn);
});
this.sequenceNumber = Date.now() | 0;
this.log.info('socket.io started');
};
@@ -244,7 +265,7 @@ Manager.prototype.disabled = function (key) {
Manager.prototype.configure = function (env, fn) {
if ('function' == typeof env) {
env.call(this);
} else if (env == process.env.NODE_ENV) {
} else if (env == (process.env.NODE_ENV || 'development')) {
fn.call(this);
}
@@ -262,7 +283,6 @@ Manager.prototype.initStore = function () {
this.connected = {};
this.open = {};
this.closed = {};
this.closedA = [];
this.rooms = {};
this.roomClients = {};
@@ -330,14 +350,21 @@ Manager.prototype.onConnect = function (id) {
Manager.prototype.onOpen = function (id) {
this.open[id] = true;
// if we were buffering messages for the client, clear them
if (this.closed[id]) {
var self = this;
this.closedA.splice(this.closedA.indexOf(id), 1);
this.store.unsubscribe('dispatch:' + id, function () {
delete self.closed[id];
var transport = self.transports[id];
if (self.closed[id] && self.closed[id].length && transport) {
// if we have buffered messages that accumulate between calling
// onOpen an this async callback, send them if the transport is
// still open, otherwise leave them buffered
if (transport.open) {
transport.payload(self.closed[id]);
self.closed[id] = [];
}
}
});
}
@@ -408,7 +435,10 @@ Manager.prototype.onLeave = function (id, room) {
if (!this.rooms[room].length) {
delete this.rooms[room];
}
delete this.roomClients[id][room];
if (this.roomClients[id]) {
delete this.roomClients[id][room];
}
}
};
@@ -424,7 +454,6 @@ Manager.prototype.onClose = function (id) {
}
this.closed[id] = [];
this.closedA.push(id);
var self = this;
@@ -467,8 +496,9 @@ Manager.prototype.onClientMessage = function (id, packet) {
Manager.prototype.onClientDisconnect = function (id, reason) {
for (var name in this.namespaces) {
if (this.roomClients[id][name]) {
this.namespaces[name].handleDisconnect(id, reason);
if (this.namespaces.hasOwnProperty(name)) {
this.namespaces[name].handleDisconnect(id, reason, typeof this.roomClients[id] !== 'undefined' &&
typeof this.roomClients[id][name] !== 'undefined');
}
}
@@ -499,12 +529,13 @@ Manager.prototype.onDisconnect = function (id, local) {
if (this.closed[id]) {
delete this.closed[id];
this.closedA.splice(this.closedA.indexOf(id), 1);
}
if (this.roomClients[id]) {
for (var room in this.roomClients[id]) {
this.onLeave(id, room);
if (this.roomClients[id].hasOwnProperty(room)) {
this.onLeave(id, room);
}
}
delete this.roomClients[id]
}
@@ -608,12 +639,15 @@ Manager.prototype.handleClient = function (data, req) {
, store = this.store
, self = this;
// handle sync disconnect xhrs
if (undefined != data.query.disconnect) {
if (this.transports[data.id] && this.transports[data.id].open) {
this.transports[data.id].onForcedDisconnect();
} else {
this.store.publish('disconnect-force:' + data.id);
}
req.res.writeHead(200);
req.res.end();
return;
}
@@ -626,6 +660,11 @@ Manager.prototype.handleClient = function (data, req) {
var transport = new transports[data.transport](this, data, req)
, handshaken = this.handshaken[data.id];
if (transport.disconnected) {
// failed during transport setup
req.connection.end();
return;
}
if (handshaken) {
if (transport.open) {
if (this.closed[data.id] && this.closed[data.id].length) {
@@ -649,11 +688,13 @@ Manager.prototype.handleClient = function (data, req) {
// initialize the socket for all namespaces
for (var i in this.namespaces) {
var socket = this.namespaces[i].socket(data.id, true);
if (this.namespaces.hasOwnProperty(i)) {
var socket = this.namespaces[i].socket(data.id, true);
// echo back connect packet and fire connection event
if (i === '') {
this.namespaces[i].handlePacket(data.id, { type: 'connect' });
// echo back connect packet and fire connection event
if (i === '') {
this.namespaces[i].handlePacket(data.id, { type: 'connect' });
}
}
}
@@ -681,8 +722,22 @@ Manager.prototype.handleClient = function (data, req) {
*/
Manager.prototype.generateId = function () {
return Math.abs(Math.random() * Math.random() * Date.now() | 0).toString()
+ Math.abs(Math.random() * Math.random() * Date.now() | 0).toString();
var rand = new Buffer(15); // multiple of 3 for base64
if (!rand.writeInt32BE) {
return Math.abs(Math.random() * Math.random() * Date.now() | 0).toString()
+ Math.abs(Math.random() * Math.random() * Date.now() | 0).toString();
}
this.sequenceNumber = (this.sequenceNumber + 1) | 0;
rand.writeInt32BE(this.sequenceNumber, 11);
if (crypto.randomBytes) {
crypto.randomBytes(12).copy(rand);
} else {
// not secure for node 0.4
[0, 4, 8].forEach(function(i) {
rand.writeInt32BE(Math.random() * Math.pow(2, 32) | 0, i);
});
}
return rand.toString('base64').replace(/\//g, '_').replace(/\+/g, '-');
};
/**
@@ -699,7 +754,7 @@ Manager.prototype.handleHandshake = function (data, req, res) {
};
function writeErr (status, message) {
if (data.query.jsonp) {
if (data.query.jsonp && jsonpolling_re.test(data.query.jsonp)) {
res.writeHead(200, { 'Content-Type': 'application/javascript' });
res.end('io.j[' + data.query.jsonp + '](new Error("' + message + '"));');
} else {
@@ -722,11 +777,8 @@ Manager.prototype.handleHandshake = function (data, req, res) {
if (origin) {
// https://developer.mozilla.org/En/HTTP_Access_Control
headers['Access-Control-Allow-Origin'] = '*';
if (req.headers.cookie) {
headers['Access-Control-Allow-Credentials'] = 'true';
}
headers['Access-Control-Allow-Origin'] = origin;
headers['Access-Control-Allow-Credentials'] = 'true';
}
this.authorize(handshakeData, function (err, authorized, newData) {
@@ -741,7 +793,7 @@ Manager.prototype.handleHandshake = function (data, req, res) {
, self.transports(data).join(',')
].join(':');
if (data.query.jsonp) {
if (data.query.jsonp && jsonpolling_re.test(data.query.jsonp)) {
hs = 'io.j[' + data.query.jsonp + '](' + JSON.stringify(hs) + ');';
res.writeHead(200, { 'Content-Type': 'application/javascript' });
} else {
@@ -776,12 +828,12 @@ Manager.prototype.handshakeData = function (data) {
connectionAddress = {
address: connection.remoteAddress
, port: connection.remotePort
};
};
} else if (connection.socket && connection.socket.remoteAddress) {
connectionAddress = {
address: connection.socket.remoteAddress
, port: connection.socket.remotePort
};
};
}
return {
@@ -815,6 +867,7 @@ Manager.prototype.verifyOrigin = function (request) {
if (origin) {
try {
var parts = url.parse(origin);
parts.port = parts.port || 80;
var ok =
~origins.indexOf(parts.hostname + ':' + parts.port) ||
~origins.indexOf(parts.hostname + ':*') ||
@@ -826,7 +879,7 @@ Manager.prototype.verifyOrigin = function (request) {
}
}
else {
this.log.warn('origin missing from handshake, yet required by config');
this.log.warn('origin missing from handshake, yet required by config');
}
return false;
};
@@ -899,8 +952,17 @@ var regexp = /^\/([^\/]+)\/?([^\/]+)?\/?([^\/]+)?\/?$/
Manager.prototype.checkRequest = function (req) {
var resource = this.get('resource');
if (req.url.substr(0, resource.length) == resource) {
var uri = url.parse(req.url.substr(resource.length), true)
var match;
if (typeof resource === 'string') {
match = req.url.substr(0, resource.length);
if (match !== resource) match = null;
} else {
match = resource.exec(req.url);
if (match) match = match[0];
}
if (match) {
var uri = url.parse(req.url.substr(match.length), true)
, path = uri.pathname || ''
, pieces = path.match(regexp);

View File

@@ -224,9 +224,9 @@ SocketNamespace.prototype.authorization = function (fn) {
* @api private
*/
SocketNamespace.prototype.handleDisconnect = function (sid, reason) {
SocketNamespace.prototype.handleDisconnect = function (sid, reason, raiseOnDisconnect) {
if (this.sockets[sid] && this.sockets[sid].readable) {
this.sockets[sid].onDisconnect(reason);
if (raiseOnDisconnect) this.sockets[sid].onDisconnect(reason);
delete this.sockets[sid];
}
};

View File

@@ -234,7 +234,7 @@ exports.decodePayload = function (data) {
for (var i = 1, length = ''; i < data.length; i++) {
if (data[i] == '\ufffd') {
ret.push(exports.decodePacket(data.substr(i + 1).substr(0, length)));
ret.push(exports.decodePacket(data.substr(i + 1, length)));
i += Number(length) + 1;
length = '';
} else {

View File

@@ -15,7 +15,7 @@ var client = require('socket.io-client');
* Version.
*/
exports.version = '0.8.6';
exports.version = '0.9.11';
/**
* Supported protocol version.
@@ -39,6 +39,13 @@ exports.clientVersion = client.version;
*/
exports.listen = function (server, options, fn) {
if ('function' == typeof server) {
console.warn('Socket.IO\'s `listen()` method expects an `http.Server` instance\n'
+ 'as its first parameter. Are you migrating from Express 2.x to 3.x?\n'
+ 'If so, check out the "Socket.IO compatibility" section at:\n'
+ 'https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x');
}
if ('function' == typeof options) {
fn = options;
options = {};

View File

@@ -291,12 +291,19 @@ Socket.prototype.disconnect = function () {
if (!this.disconnected) {
this.log.info('booting client');
if (this.manager.transports[this.id] && this.manager.transports[this.id].open) {
this.manager.transports[this.id].onForcedDisconnect();
if ('' === this.namespace.name) {
if (this.manager.transports[this.id] && this.manager.transports[this.id].open) {
this.manager.transports[this.id].onForcedDisconnect();
} else {
this.manager.onClientDisconnect(this.id);
this.manager.store.publish('disconnect:' + this.id);
}
} else {
this.manager.onClientDisconnect(this.id);
this.manager.store.publish('disconnect:' + this.id);
this.packet({type: 'disconnect'});
this.manager.onLeave(this.id, this.namespace.name);
this.$emit('disconnect', 'booted');
}
}
return this;

View File

@@ -178,7 +178,7 @@ Static.prototype.gzip = function (data, callback) {
buffer.length = 0;
});
gzip.on('exit', function () {
gzip.on('close', function () {
if (err) return callback(err);
var size = 0

View File

@@ -455,7 +455,7 @@ Transport.prototype.onClose = function () {
Transport.prototype.end = function (reason) {
if (!this.disconnected) {
this.log.info('transport end');
this.log.info('transport end (' + reason + ')');
var local = this.manager.transports[this.id];

View File

@@ -1,4 +1,3 @@
/*!
* socket.io-node
* Copyright(c) 2011 LearnBoost <dev@learnboost.com>
@@ -49,13 +48,20 @@ FlashSocket.prototype.name = 'flashsocket';
* @api private
*/
var server;
FlashSocket.init = function (manager) {
var server;
function create () {
// Drop out immediately if the user has
// disabled the flash policy server
if (!manager.get('flash policy server')) {
return;
}
server = require('policyfile').createServer({
log: function(msg){
manager.log.info(msg.toLowerCase());
manager.log.info(msg);
}
}, manager.get('origins'));
@@ -80,10 +86,32 @@ FlashSocket.init = function (manager) {
// destory the server and create a new server
manager.on('set:flash policy port', function (value, key) {
var transports = manager.get('transports');
if (~transports.indexOf('flashsocket')) {
if (server) {
if (server.port === value) return;
// destroy the server and rebuild it on a new port
try {
server.close();
}
catch (e) { /* ignore exception. could e.g. be that the server isn't started yet */ }
}
create();
}
});
if (server && server.port !== value && ~transports.indexOf('flashsocket')) {
// destroy the server and rebuild it on a new port
server.close();
// create or destroy the server
manager.on('set:flash policy server', function (value, key) {
var transports = manager.get('transports');
if (~transports.indexOf('flashsocket')) {
if (server && !value) {
// destroy the server
try {
server.close();
}
catch (e) { /* ignore exception. could e.g. be that the server isn't started yet */ }
}
} else if (!server && value) {
// create the server
create();
}
});
@@ -94,7 +122,6 @@ FlashSocket.init = function (manager) {
create();
}
});
// check if we need to initialize at start
if (~manager.get('transports').indexOf('flashsocket')){
create();

View File

@@ -43,6 +43,18 @@ HTTPPolling.prototype.__proto__ = HTTPTransport.prototype;
HTTPPolling.prototype.name = 'httppolling';
/**
* Override setHandlers
*
* @api private
*/
HTTPPolling.prototype.setHandlers = function () {
HTTPTransport.prototype.setHandlers.call(this);
this.socket.removeListener('end', this.bound.end);
this.socket.removeListener('close', this.bound.close);
};
/**
* Removes heartbeat timeouts for polling.
*/
@@ -128,8 +140,8 @@ HTTPPolling.prototype.write = function (data, close) {
* @api private
*/
HTTPPolling.prototype.end = function () {
HTTPPolling.prototype.end = function (reason) {
this.clearPollTimeout();
return HTTPTransport.prototype.end.call(this);
return HTTPTransport.prototype.end.call(this, reason);
};

View File

@@ -42,15 +42,24 @@ HTTPTransport.prototype.__proto__ = Transport.prototype;
*/
HTTPTransport.prototype.handleRequest = function (req) {
// Always set the response in case an error is returned to the client
this.response = req.res;
if (req.method == 'POST') {
var buffer = ''
, res = req.res
, origin = req.headers.origin
, headers = { 'Content-Length': 1 }
, headers = { 'Content-Length': 1, 'Content-Type': 'text/plain; charset=UTF-8' }
, self = this;
req.on('data', function (data) {
buffer += data;
if (Buffer.byteLength(buffer) >= self.manager.get('destroy buffer size')) {
buffer = '';
req.connection.destroy();
}
});
req.on('end', function () {
@@ -60,17 +69,18 @@ HTTPTransport.prototype.handleRequest = function (req) {
self.onData(self.postEncoded ? qs.parse(buffer).d : buffer);
});
// prevent memory leaks for uncompleted requests
req.on('close', function () {
buffer = '';
self.onClose();
});
if (origin) {
// https://developer.mozilla.org/En/HTTP_Access_Control
headers['Access-Control-Allow-Origin'] = '*';
if (req.headers.cookie) {
headers['Access-Control-Allow-Credentials'] = 'true';
}
headers['Access-Control-Allow-Origin'] = origin;
headers['Access-Control-Allow-Credentials'] = 'true';
}
} else {
this.response = req.res;
Transport.prototype.handleRequest.call(this, req);
}
};

View File

@@ -10,6 +10,7 @@
*/
var HTTPPolling = require('./http-polling');
var jsonpolling_re = /^\d+$/
/**
* Export the constructor.
@@ -29,7 +30,7 @@ function JSONPPolling (mng, data, req) {
this.head = 'io.j[0](';
this.foot = ');';
if (data.query.i) {
if (data.query.i && jsonpolling_re.test(data.query.i)) {
this.head = 'io.j[' + data.query.i + '](';
}
};

View File

@@ -1,4 +1,3 @@
/*!
* socket.io-node
* Copyright(c) 2011 LearnBoost <dev@learnboost.com>
@@ -88,10 +87,15 @@ WebSocket.prototype.onSocketConnect = function () {
return;
}
var origin = this.req.headers.origin
, location = (this.socket.encrypted ? 'wss' : 'ws')
+ '://' + this.req.headers.host + this.req.url
, waitingForNonce = false;
var origin = this.req.headers['origin']
, waitingForNonce = false;
if(this.manager.settings['match origin protocol']){
location = (origin.indexOf('https')>-1 ? 'wss' : 'ws') + '://' + this.req.headers.host + this.req.url;
}else if(this.socket.encrypted){
location = 'wss://' + this.req.headers.host + this.req.url;
}else{
location = 'ws://' + this.req.headers.host + this.req.url;
}
if (this.req.headers['sec-websocket-key1']) {
// If we don't have the nonce yet, wait for it (HAProxy compatibility).

View File

@@ -91,14 +91,17 @@ WebSocket.prototype.protocolVersion = '07-12';
WebSocket.prototype.onSocketConnect = function () {
var self = this;
if (this.req.headers.upgrade.toLowerCase() !== 'websocket') {
if (typeof this.req.headers.upgrade === 'undefined' ||
this.req.headers.upgrade.toLowerCase() !== 'websocket') {
this.log.warn(this.name + ' connection invalid');
this.end();
return;
}
var origin = this.req.headers['sec-websocket-origin']
, location = (this.socket.encrypted ? 'wss' : 'ws')
, location = ((this.manager.settings['match origin protocol'] ?
origin.match(/^https/) : this.socket.encrypted) ?
'wss' : 'ws')
+ '://' + this.req.headers.host + this.req.url;
if (!this.verifyOrigin(origin)) {
@@ -158,6 +161,7 @@ WebSocket.prototype.verifyOrigin = function (origin) {
if (origin) {
try {
var parts = url.parse(origin);
parts.port = parts.port || 80;
var ok =
~origins.indexOf(parts.hostname + ':' + parts.port) ||
~origins.indexOf(parts.hostname + ':*') ||
@@ -504,7 +508,9 @@ Parser.prototype.expect = function(what, length, handler) {
*/
Parser.prototype.processPacket = function (data) {
if ((data[0] & 0x70) != 0) this.error('reserved fields must be empty');
if ((data[0] & 0x70) != 0) {
this.error('reserved fields must be empty');
}
this.state.lastFragment = (data[0] & 0x80) == 0x80;
this.state.masked = (data[1] & 0x80) == 0x80;
var opcode = data[0] & 0xf;

View File

@@ -1,4 +1,3 @@
/*!
* socket.io-node
* Copyright(c) 2011 LearnBoost <dev@learnboost.com>
@@ -91,14 +90,17 @@ WebSocket.prototype.protocolVersion = '16';
WebSocket.prototype.onSocketConnect = function () {
var self = this;
if (this.req.headers.upgrade.toLowerCase() !== 'websocket') {
if (typeof this.req.headers.upgrade === 'undefined' ||
this.req.headers.upgrade.toLowerCase() !== 'websocket') {
this.log.warn(this.name + ' connection invalid');
this.end();
return;
}
var origin = this.req.headers['origin']
, location = (this.socket.encrypted ? 'wss' : 'ws')
var origin = this.req.headers['origin'] || ''
, location = ((this.manager.settings['match origin protocol'] ?
origin.match(/^https/) : this.socket.encrypted) ?
'wss' : 'ws')
+ '://' + this.req.headers.host + this.req.url;
if (!this.verifyOrigin(origin)) {
@@ -158,6 +160,7 @@ WebSocket.prototype.verifyOrigin = function (origin) {
if (origin) {
try {
var parts = url.parse(origin);
parts.port = parts.port || 80;
var ok =
~origins.indexOf(parts.hostname + ':' + parts.port) ||
~origins.indexOf(parts.hostname + ':*') ||
@@ -504,7 +507,10 @@ Parser.prototype.expect = function(what, length, handler) {
*/
Parser.prototype.processPacket = function (data) {
if ((data[0] & 0x70) != 0) this.error('reserved fields must be empty');
if ((data[0] & 0x70) != 0) {
this.error('reserved fields must be empty');
return;
}
this.state.lastFragment = (data[0] & 0x80) == 0x80;
this.state.masked = (data[1] & 0x80) == 0x80;
var opcode = data[0] & 0xf;

View File

@@ -59,11 +59,8 @@ XHRPolling.prototype.doWrite = function (data) {
if (origin) {
// https://developer.mozilla.org/En/HTTP_Access_Control
headers['Access-Control-Allow-Origin'] = '*';
if (this.req.headers.cookie) {
headers['Access-Control-Allow-Credentials'] = 'true';
}
headers['Access-Control-Allow-Origin'] = origin;
headers['Access-Control-Allow-Credentials'] = 'true';
}
this.response.writeHead(200, headers);

View File

@@ -1,6 +1,6 @@
{
"name": "socket.io"
, "version": "0.8.6"
, "version": "0.9.11"
, "description": "Real-time apps made cross-browser & easy with a WebSocket-like API"
, "homepage": "http://socket.io"
, "keywords": ["websocket", "socket", "realtime", "socket.io", "comet", "ajax"]
@@ -16,18 +16,22 @@
, "url": "https://github.com/LearnBoost/socket.io.git"
}
, "dependencies": {
"socket.io-client": "0.8.6"
"socket.io-client": "0.9.11"
, "policyfile": "0.0.4"
, "redis": "0.6.7"
}
, "devDependencies": {
"expresso": "0.7.7"
, "should": "0.0.4"
, "assertvanish": "0.0.3-1"
"expresso": "0.9.2"
, "should": "*"
, "benchmark": "0.2.2"
, "microtime": "0.1.3-1"
, "colors": "0.5.1"
}
, "optionalDependencies": {
"redis": "0.7.3"
}
, "main": "index"
, "engines": { "node": ">= 0.4.0" }
, "scripts": {
"test": "make test"
}
}

View File

@@ -5,7 +5,7 @@ var events = require('events');
var http = require('http');
var net = require('net');
var urllib = require('url');
var sys = require('sys');
var sys = require('util');
var FRAME_NO = 0;
var FRAME_LO = 1;
@@ -347,7 +347,6 @@ var WebSocket = function(url, proto, opts) {
// that we've closed.
var finishClose = self.finishClose = function() {
readyState = CLOSED;
if (stream) {
stream.end();
stream.destroy();
@@ -469,29 +468,45 @@ var WebSocket = function(url, proto, opts) {
// that http.Client passes its constructor arguments through,
// un-inspected to net.Stream.connect(). The latter accepts a
// string as its first argument to connect to a UNIX socket.
var httpClient = undefined;
var opt = {};
var agent = null;
switch (getUrlScheme(url)) {
case 'ws':
var u = urllib.parse(url);
httpClient = http.createClient(u.port || 80, u.hostname);
httpPath = (u.pathname || '/') + (u.search || '');
httpHeaders.Host = u.hostname + (u.port ? (":" + u.port) : "");
agent = new http.Agent({
host: u.hostname,
port: u.port || 80
});
opt.agent = agent;
opt.host = u.hostname;
opt.port = u.port || 80;
opt.path = (u.pathname || '/') + (u.search || '');
opt.headers = httpHeaders;
break;
case 'ws+unix':
var sockPath = url.substring('ws+unix://'.length, url.length);
httpClient = http.createClient(sockPath);
httpHeaders.Host = 'localhost';
var u = urllib.parse(url);
agent = new http.Agent({
host: 'localhost',
port: sockPath
});
opt.agent = agent;
opt.host = 'localhost';
opt.path = sockPath;
opt.headers = httpHeaders;
break;
default:
throw new Error('Invalid URL scheme \'' + urlScheme + '\' specified.');
}
httpClient.on('upgrade', (function() {
var httpReq = http.request(opt, function() { });
var upgradeHandler = (function() {
var data = undefined;
return function(req, s, head) {
req.socket.setNoDelay(true);
stream = s;
if (readyState == CLOSED) {
@@ -554,7 +569,7 @@ var WebSocket = function(url, proto, opts) {
//
// XXX: This is lame. We should only remove the listeners
// that we added.
httpClient.removeAllListeners('upgrade');
httpReq.removeAllListeners('upgrade');
stream.removeAllListeners('data');
stream.on('data', dataListener);
@@ -582,13 +597,9 @@ var WebSocket = function(url, proto, opts) {
stream.emit('data', head);
};
})());
httpClient.on('error', function(e) {
httpClient.end();
errorListener(e);
});
var httpReq = httpClient.request(httpPath, httpHeaders);
})();
agent.on('upgrade', upgradeHandler); // node v0.4
httpReq.on('upgrade', upgradeHandler); // node v0.5+
httpReq.write(challenge, 'binary');
httpReq.end();

View File

@@ -9,7 +9,7 @@
* Test dependencies.
*/
var io = require('socket.io')
var io = require('../')
, parser = io.parser
, http = require('http')
, https = require('https')
@@ -91,8 +91,25 @@ HTTPClient.prototype.request = function (path, opts, fn) {
*/
HTTPClient.prototype.end = function () {
this.agent.sockets.forEach(function (socket) {
socket.end();
// node <v0.5 compat
if (this.agent.sockets.forEach) {
this.agent.sockets.forEach(function (socket) {
if (socket.end) socket.end();
});
return;
}
// node >=v0.5 compat
var self = this;
Object.keys(this.agent.sockets).forEach(function (socket) {
for (var i = 0, l = self.agent.sockets[socket].length; i < l; ++i) {
if (self.agent.sockets[socket][i]._handle) {
if (self.agent.sockets[socket][i]._handle.socket) {
self.agent.sockets[socket][i]._handle.socket.end();
} else {
self.agent.sockets[socket][i]._handle.owner.end();
}
}
}
});
};
@@ -214,7 +231,7 @@ function WSClient (port, sid, transport) {
this.transportName = transport || 'websocket';
WebSocket.call(
this
, 'ws://localhost:' + port + '/socket.io/'
, 'ws://localhost:' + port + '/socket.io/'
+ io.protocol + '/' + this.transportName + '/' + sid
);
};

View File

@@ -43,7 +43,7 @@ mask = function(buf, maskString) {
if (typeof buf == 'string') buf = new Buffer(buf);
var mask = getBufferFromHexString(maskString || '34 83 a8 68');
for (var i = 0; i < buf.length; ++i) {
buf[i] ^= mask[i % 4];
buf[i] ^= mask[i % 4];
}
return buf;
}
@@ -51,20 +51,20 @@ mask = function(buf, maskString) {
/**
* Returns a hex string representing the length of a message
*/
getHybiLengthAsHexString = function(len, masked) {
getHybiLengthAsHexString = function(len, masked) {
if (len < 126) {
var buf = new Buffer(1);
buf[0] = (masked ? 0x80 : 0) | len;
buf[0] = (masked ? 0x80 : 0) | len;
}
else if (len < 65536) {
var buf = new Buffer(3);
buf[0] = (masked ? 0x80 : 0) | 126;
buf[0] = (masked ? 0x80 : 0) | 126;
getBufferFromHexString(pack(4, len)).copy(buf, 1);
}
else {
var buf = new Buffer(9);
buf[0] = (masked ? 0x80 : 0) | 127;
buf[0] = (masked ? 0x80 : 0) | 127;
getBufferFromHexString(pack(16, len)).copy(buf, 1);
}
return getHexStringFromBuffer(buf);
@@ -94,6 +94,6 @@ pack = function(length, number) {
* Left pads the string 's' to a total length of 'n' with char 'c'.
*/
padl = function(s, n, c) {
padl = function(s, n, c) {
return new Array(1 + n - s.length).join(c) + s;
}

View File

@@ -9,7 +9,7 @@
* Test dependencies.
*/
var sio = require('socket.io')
var sio = require('../')
, fs = require('fs')
, http = require('http')
, https = require('https')
@@ -116,10 +116,10 @@ module.exports = {
io.server.close();
done();
});
done();
} catch (e) {
e.should.match(/EACCES/);
done();
}
}
};

View File

@@ -8,7 +8,7 @@
* Test dependencies.
*/
var sio = require('socket.io')
var sio = require('../')
, http = require('http')
, should = require('./common')
, ports = 15100;
@@ -117,6 +117,7 @@ module.exports = {
io.disable('foo');
calls.should.eql(3);
done();
},
@@ -276,6 +277,23 @@ module.exports = {
});
},
'test that a referer with implicit port 80 is accepted for foo.bar.com:80 origin': function (done) {
var port = ++ports
, io = sio.listen(port)
, cl = client(port);
io.configure(function () {
io.set('origins', 'foo.bar.com:80');
});
cl.get('/socket.io/{protocol}', { headers: { referer: 'http://foo.bar.com/something' } }, function (res, data) {
res.statusCode.should.eql(200);
cl.end();
io.server.close();
done();
});
},
'test that erroneous referer is denied for addr:* origin': function (done) {
var port = ++ports
, io = sio.listen(port)
@@ -338,7 +356,7 @@ module.exports = {
cl.get('/socket.io/{protocol}/', { headers:headers }, function (res, data) {
res.statusCode.should.eql(200);
res.headers['access-control-allow-origin'].should.eql('*');
res.headers['access-control-allow-origin'].should.eql('http://example.org:1337');
res.headers['access-control-allow-credentials'].should.eql('true');
cl.end();
@@ -426,8 +444,8 @@ module.exports = {
'test disabling heartbeats': function (done) {
var port = ++ports
, io = sio.listen(port)
, cl = client(port)
, io = create(cl)
, messages = 0
, beat = false
, ws;
@@ -446,9 +464,8 @@ module.exports = {
socket.on('disconnect', function (reason) {
beat.should.be.false;
cl.end();
ws.finishClose();
cl.end();
io.server.close();
done();
});
@@ -505,8 +522,10 @@ module.exports = {
io.rooms.foo.length.should.equal(2);
io.rooms.bar.length.should.equal(2);
io.server.close();
done();
process.nextTick(function() {
io.server.close();
done();
});
},
'test passing options directly to the Manager through listen': function (done) {
@@ -515,8 +534,10 @@ module.exports = {
io.get('resource').should.equal('/my resource');
io.get('custom').should.equal('opt');
io.server.close();
done();
process.nextTick(function() {
io.server.close();
done();
});
},
'test disabling the log': function (done) {
@@ -535,8 +556,10 @@ module.exports = {
console.log = _console;
calls.should.equal(0);
io.server.close();
done();
process.nextTick(function() {
io.server.close();
done();
});
},
'test disabling logging with colors': function (done) {
@@ -558,7 +581,9 @@ module.exports = {
console.log = _console;
calls.should.equal(2);
io.server.close();
done();
process.nextTick(function() {
io.server.close();
done();
});
}
};

View File

@@ -131,7 +131,7 @@ module.exports = {
if (data.endpoint == '/a') {
data.type.should.eql('error');
data.reason.should.eql('unauthorized')
cl.end();
ws.finishClose();
io.server.close()
@@ -154,6 +154,9 @@ module.exports = {
io.of('a')
.on('connection', function (socket){
if (connect < 2) {
return;
}
socket.broadcast.emit('b', 'test');
socket.broadcast.json.emit('json', {foo:'bar'});
socket.broadcast.send('foo');
@@ -163,7 +166,6 @@ module.exports = {
connect.should.equal(2);
message.should.equal(1);
events.should.equal(2);
cl.end();
ws1.finishClose();
ws2.finishClose();
@@ -173,16 +175,19 @@ module.exports = {
cl.handshake(function (sid) {
ws1 = websocket(cl, sid);
ws1.on('open', function() {
ws1.packet({
type: 'connect'
, endpoint: 'a'
});
});
ws1.on('message', function (data) {
if (data.type === 'connect') {
if (connect == 0) {
cl.handshake(function (sid) {
ws2 = websocket(cl, sid);
ws2.on('open', function () {
ws2.packet({
type: 'connect'
, endpoint: 'a'
});
});
});
}
++connect;
if (++calls === expected) finish();
}
@@ -197,17 +202,12 @@ module.exports = {
if (++calls === expected) finish();
}
});
cl.handshake(function (sid) {
ws2 = websocket(cl, sid);
ws2.on('open', function () {
ws2.packet({
type: 'connect'
, endpoint: 'a'
});
ws1.on('open', function() {
ws1.packet({
type: 'connect'
, endpoint: 'a'
});
})
});
})
},
@@ -282,5 +282,46 @@ module.exports = {
}
});
});
},
'disconnecting from namespace only': function (done) {
var cl = client(++ports)
, io = create(cl)
, ws1
, ws2;
io.of('/foo').on('connection', function (socket) {
socket.disconnect();
});
cl.handshake(function (sid) {
ws1 = websocket(cl, sid);
ws1.on('open', function () {
ws1.packet({
type: 'connect'
, endpoint: '/bar'
});
cl.handshake(function (sid) {
ws2 = websocket(cl, sid);
ws2.on('open', function () {
ws2.packet({
type: 'connect'
, endpoint: '/foo'
});
});
ws2.on('message', function (data) {
if ('disconnect' === data.type) {
cl.end();
ws1.finishClose();
ws2.finishClose();
io.server.close();
data.endpoint.should.eql('/foo');
done();
}
});
});
});
});
}
};

View File

@@ -3,7 +3,7 @@
* Test dependencies.
*/
var parser = require('socket.io').parser
var parser = require('../').parser
, decode = parser.decode
, should = require('./common');
@@ -95,7 +95,7 @@ module.exports = {
'decoding json packet with message id and ack data': function () {
parser.decodePacket('4:1+::{"a":"b"}').should.eql({
type: 'json'
, id: 1
, id: '1'
, ack: 'data'
, endpoint: ''
, data: { a: 'b' }
@@ -114,7 +114,7 @@ module.exports = {
'decoding an event packet with message id and ack': function () {
parser.decodePacket('5:1+::{"name":"tobi"}').should.eql({
type: 'event'
, id: 1
, id: '1'
, ack: 'data'
, endpoint: ''
, name: 'tobi'
@@ -143,7 +143,7 @@ module.exports = {
'decoding a message packet with id and endpoint': function () {
parser.decodePacket('3:5:/tobi').should.eql({
type: 'message'
, id: 5
, id: '5'
, ack: true
, endpoint: '/tobi'
, data: ''
@@ -245,7 +245,7 @@ module.exports = {
'encoding json packet with message id and ack data': function () {
parser.encodePacket({
type: 'json'
, id: 1
, id: '1'
, ack: 'data'
, endpoint: ''
, data: { a: 'b' }
@@ -264,7 +264,7 @@ module.exports = {
'encoding an event packet with message id and ack': function () {
parser.encodePacket({
type: 'event'
, id: 1
, id: '1'
, ack: 'data'
, endpoint: ''
, name: 'tobi'
@@ -292,7 +292,7 @@ module.exports = {
'encoding a message packet with id and endpoint': function () {
parser.encodePacket({
type: 'message'
, id: 5
, id: '5'
, ack: true
, endpoint: '/tobi'
, data: ''

View File

@@ -1,15 +0,0 @@
/**
* Test dependencies.
*/
var sio = require('socket.io')
, should = require('./common');
/**
* Test.
*/
module.exports = {
};

View File

@@ -9,7 +9,7 @@
* Test dependencies.
*/
var sio = require('socket.io')
var sio = require('../')
, should = require('./common')
, ports = 15400;
@@ -30,8 +30,10 @@ module.exports = {
(!!io.static.has('/static/flashsocket/WebSocketMain.swf')).should.be.true;
(!!io.static.has('/static/flashsocket/WebSocketMainInsecure.swf')).should.be.true;
io.server.close();
done();
process.nextTick(function() {
io.server.close();
done();
});
},
'test that static files are correctly looked up': function (done) {
@@ -41,8 +43,10 @@ module.exports = {
(!!io.static.has('/socket.io.js')).should.be.true;
(!!io.static.has('/invalidfilehereplease.js')).should.be.false;
io.server.close();
done();
process.nextTick(function() {
io.server.close();
done();
});
},
'test that the client is served': function (done) {
@@ -90,7 +94,7 @@ module.exports = {
'test that the client is build with the enabled transports': function (done) {
var port = ++ports
, io = sio.listen(port)
, io = sio.listen(port)
, cl = client(port);
io.set('transports', ['websocket']);
@@ -448,7 +452,7 @@ module.exports = {
cl.get('/socket.io/socket.io.js', function (res, data) {
res.headers['content-type'].should.eql('application/javascript');
res.headers['content-length'].should.eql(13);
res.headers['content-length'].should.eql('13');
res.headers.etag.should.eql('1.0');
data.should.eql('custom_client');

View File

@@ -5,7 +5,7 @@
* @api private
*/
var sio = require('socket.io')
var sio = require('../')
, should = require('should')
, MemoryStore = sio.MemoryStore;
@@ -45,7 +45,7 @@ module.exports = {
client.set('b', 'c', function (err) {
should.strictEqual(err, null);
client.set('c', 'd', function (err) {
should.strictEqual(err, null);

View File

@@ -5,7 +5,7 @@
* @api private
*/
var sio = require('socket.io')
var sio = require('../')
, redis = require('redis')
, should = require('should')
, RedisStore = sio.RedisStore;
@@ -95,7 +95,7 @@ module.exports = {
client.set('b', 'c', function (err) {
should.strictEqual(err, null);
client.set('c', 'd', function (err) {
should.strictEqual(err, null);

View File

@@ -9,7 +9,7 @@
* Test dependencies.
*/
var sio = require('socket.io')
var sio = require('../')
, net = require('net')
, http = require('http')
, should = require('./common')
@@ -30,7 +30,7 @@ function FlashSocket (port, sid) {
WebSocket.call(
this
, 'ws://localhost:' + port + '/socket.io/'
, 'ws://localhost:' + port + '/socket.io/'
+ sio.protocol + '/flashsocket/' + sid
);
};
@@ -104,7 +104,7 @@ module.exports = {
netConnection(port, function (err, data){
should.strictEqual(err, null);
data.toString().should.include.string('<cross-domain-policy>');
data.toString().should.match(/<cross-domain-policy>/);
this.destroy();
io.flashPolicyServer.close();
@@ -133,7 +133,7 @@ module.exports = {
netConnection(next, function (err, data){
should.strictEqual(err, null);
data.toString().should.include.string('<cross-domain-policy>');
data.toString().should.match(/<cross-domain-policy>/);
this.destroy();
io.flashPolicyServer.close();
@@ -159,7 +159,7 @@ module.exports = {
server.origins.should.not.contain('google.com:80');
server.origins.should.contain('foo.bar:80');
server.origins.should.contain('socket.io:1337');
server.buffer.toString('utf8').should.include.string('socket.io');
server.buffer.toString('utf8').should.match(/socket\.io/);
io.flashPolicyServer.close();
done();

View File

@@ -9,7 +9,7 @@
* Test dependencies.
*/
var sio = require('socket.io')
var sio = require('../')
, should = require('./common')
, HTTPClient = should.HTTPClient
, parser = sio.parser

View File

@@ -9,7 +9,7 @@
* Test dependencies.
*/
var sio = require('socket.io')
var sio = require('../')
, should = require('./common')
, qs = require('querystring')
, HTTPClient = should.HTTPClient
@@ -250,15 +250,14 @@ module.exports = {
});
},
'test the disconnection event when the client sends ?disconnect req':
function (done) {
'test the disconnection event when the client sends ?disconnect req': function (done) {
var cl = client(++ports)
, io = create(cl)
, disconnected = false
, sid;
io.configure(function () {
io.set('close timeout', .05);
io.set('close timeout', .1);
});
io.sockets.on('connection', function (socket) {
@@ -279,12 +278,17 @@ module.exports = {
msgs.should.have.length(1);
msgs[0].should.eql({ type: 'disconnect', endpoint: '' });
disconnected.should.be.true;
cl.end();
io.server.close();
cl.end();
done();
});
cl.get('/socket.io/{protocol}/jsonp-polling/' + sid + '/?disconnect');
// with the new http bits in node 0.5, there's no guarantee that
// the previous request is actually dispatched (and received) before the following
// reset call is sent. to not waste more time on a workaround, a timeout is added.
setTimeout(function() {
cl.get('/socket.io/{protocol}/jsonp-polling/' + sid + '/?disconnect');
}, 500);
});
});
},
@@ -621,7 +625,7 @@ module.exports = {
io.configure(function () {
io.set('polling duration', .2);
io.set('close timeout', .2);
io.set('close timeout', .5);
});
io.sockets.on('connection', function (socket) {

View File

@@ -2,7 +2,7 @@
* Test dependencies.
*/
var assert = require('assert');
var assert = require('assert');
var Parser = require('../lib/transports/websocket/hybi-07-12.js').Parser;
require('./hybi-common');
@@ -14,38 +14,38 @@ module.exports = {
'can parse unmasked text message': function() {
var p = new Parser();
var packet = '81 05 48 65 6c 6c 6f';
var gotData = false;
p.on('data', function(data) {
gotData = true;
assert.equal('Hello', data);
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
'can parse close message': function() {
var p = new Parser();
var packet = '88 00';
var gotClose = false;
p.on('close', function(data) {
gotClose = true;
});
p.add(getBufferFromHexString(packet));
assert.ok(gotClose);
},
'can parse masked text message': function() {
var p = new Parser();
var packet = '81 93 34 83 a8 68 01 b9 92 52 4f a1 c6 09 59 e6 8a 52 16 e6 cb 00 5b a1 d5';
var gotData = false;
p.on('data', function(data) {
gotData = true;
assert.equal('5:::{"name":"echo"}', data);
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
@@ -54,13 +54,13 @@ module.exports = {
var message = 'A';
for (var i = 0; i < 300; ++i) message += (i % 5).toString();
var packet = '81 FE ' + pack(4, message.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68'));
var gotData = false;
p.on('data', function(data) {
gotData = true;
assert.equal(message, data);
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
@@ -75,7 +75,7 @@ module.exports = {
gotData = true;
assert.equal(message, data);
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
@@ -87,13 +87,13 @@ module.exports = {
var msgpiece2 = message.substr(150);
var packet1 = '01 FE ' + pack(4, msgpiece1.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece1, '34 83 a8 68'));
var packet2 = '80 FE ' + pack(4, msgpiece2.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece2, '34 83 a8 68'));
var gotData = false;
p.on('data', function(data) {
gotData = true;
gotData = true;
assert.equal(message, data);
});
p.add(getBufferFromHexString(packet1));
p.add(getBufferFromHexString(packet2));
assert.ok(gotData);
@@ -102,25 +102,25 @@ module.exports = {
var p = new Parser();
var message = 'Hello';
var packet = '89 FE ' + pack(4, message.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68'));
var gotPing = false;
p.on('ping', function(data) {
gotPing = true;
assert.equal(message, data);
});
p.add(getBufferFromHexString(packet));
assert.ok(gotPing);
},
'can parse a ping with no data': function() {
var p = new Parser();
var packet = '89 00';
var gotPing = false;
p.on('ping', function(data) {
gotPing = true;
});
p.add(getBufferFromHexString(packet));
assert.ok(gotPing);
},
@@ -128,16 +128,16 @@ module.exports = {
var p = new Parser();
var message = 'A';
for (var i = 0; i < 300; ++i) message += (i % 5).toString();
var msgpiece1 = message.substr(0, 150);
var packet1 = '01 FE ' + pack(4, msgpiece1.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece1, '34 83 a8 68'));
var pingMessage = 'Hello';
var pingPacket = '89 FE ' + pack(4, pingMessage.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(pingMessage, '34 83 a8 68'));
var msgpiece2 = message.substr(150);
var packet2 = '80 FE ' + pack(4, msgpiece2.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece2, '34 83 a8 68'));
var gotData = false;
p.on('data', function(data) {
gotData = true;
@@ -148,7 +148,7 @@ module.exports = {
gotPing = true;
assert.equal(pingMessage, data);
});
p.add(getBufferFromHexString(packet1));
p.add(getBufferFromHexString(pingPacket));
p.add(getBufferFromHexString(packet2));
@@ -159,16 +159,16 @@ module.exports = {
var p = new Parser();
var message = 'A';
for (var i = 0; i < 300; ++i) message += (i % 5).toString();
var msgpiece1 = message.substr(0, 150);
var packet1 = '01 FE ' + pack(4, msgpiece1.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece1, '34 83 a8 68'));
var pingMessage = 'Hello';
var pingPacket = '89 FE ' + pack(4, pingMessage.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(pingMessage, '34 83 a8 68'));
var msgpiece2 = message.substr(150);
var packet2 = '80 FE ' + pack(4, msgpiece2.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece2, '34 83 a8 68'));
var gotData = false;
p.on('data', function(data) {
gotData = true;
@@ -179,7 +179,7 @@ module.exports = {
gotPing = true;
assert.equal(pingMessage, data);
});
var buffers = [];
buffers = buffers.concat(splitBuffer(getBufferFromHexString(packet1)));
buffers = buffers.concat(splitBuffer(getBufferFromHexString(pingPacket)));
@@ -195,7 +195,7 @@ module.exports = {
var length = 100;
var message = new Buffer(length);
for (var i = 0; i < length; ++i) message[i] = i % 256;
var originalMessage = getHexStringFromBuffer(message);
var originalMessage = getHexStringFromBuffer(message);
var packet = '82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68'));
var gotData = false;
@@ -203,7 +203,7 @@ module.exports = {
gotData = true;
assert.equal(originalMessage, getHexStringFromBuffer(data));
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
@@ -212,7 +212,7 @@ module.exports = {
var length = 256;
var message = new Buffer(length);
for (var i = 0; i < length; ++i) message[i] = i % 256;
var originalMessage = getHexStringFromBuffer(message);
var originalMessage = getHexStringFromBuffer(message);
var packet = '82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68'));
var gotData = false;
@@ -220,7 +220,7 @@ module.exports = {
gotData = true;
assert.equal(originalMessage, getHexStringFromBuffer(data));
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
@@ -229,7 +229,7 @@ module.exports = {
var length = 200 * 1024;
var message = new Buffer(length);
for (var i = 0; i < length; ++i) message[i] = i % 256;
var originalMessage = getHexStringFromBuffer(message);
var originalMessage = getHexStringFromBuffer(message);
var packet = '82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68'));
var gotData = false;
@@ -237,7 +237,7 @@ module.exports = {
gotData = true;
assert.equal(originalMessage, getHexStringFromBuffer(data));
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
@@ -246,7 +246,7 @@ module.exports = {
var length = 200 * 1024;
var message = new Buffer(length);
for (var i = 0; i < length; ++i) message[i] = i % 256;
var originalMessage = getHexStringFromBuffer(message);
var originalMessage = getHexStringFromBuffer(message);
var packet = '82 ' + getHybiLengthAsHexString(length, false) + ' ' + getHexStringFromBuffer(message);
var gotData = false;
@@ -254,7 +254,7 @@ module.exports = {
gotData = true;
assert.equal(originalMessage, getHexStringFromBuffer(data));
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},

View File

@@ -2,7 +2,7 @@
* Test dependencies.
*/
var assert = require('assert');
var assert = require('assert');
var Parser = require('../lib/transports/websocket/hybi-16.js').Parser;
require('./hybi-common');
@@ -14,38 +14,38 @@ module.exports = {
'can parse unmasked text message': function() {
var p = new Parser();
var packet = '81 05 48 65 6c 6c 6f';
var gotData = false;
p.on('data', function(data) {
gotData = true;
assert.equal('Hello', data);
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
'can parse close message': function() {
var p = new Parser();
var packet = '88 00';
var gotClose = false;
p.on('close', function(data) {
gotClose = true;
});
p.add(getBufferFromHexString(packet));
assert.ok(gotClose);
},
'can parse masked text message': function() {
var p = new Parser();
var packet = '81 93 34 83 a8 68 01 b9 92 52 4f a1 c6 09 59 e6 8a 52 16 e6 cb 00 5b a1 d5';
var gotData = false;
p.on('data', function(data) {
gotData = true;
assert.equal('5:::{"name":"echo"}', data);
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
@@ -54,13 +54,13 @@ module.exports = {
var message = 'A';
for (var i = 0; i < 300; ++i) message += (i % 5).toString();
var packet = '81 FE ' + pack(4, message.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68'));
var gotData = false;
p.on('data', function(data) {
gotData = true;
assert.equal(message, data);
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
@@ -75,7 +75,7 @@ module.exports = {
gotData = true;
assert.equal(message, data);
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
@@ -87,13 +87,13 @@ module.exports = {
var msgpiece2 = message.substr(150);
var packet1 = '01 FE ' + pack(4, msgpiece1.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece1, '34 83 a8 68'));
var packet2 = '80 FE ' + pack(4, msgpiece2.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece2, '34 83 a8 68'));
var gotData = false;
p.on('data', function(data) {
gotData = true;
gotData = true;
assert.equal(message, data);
});
p.add(getBufferFromHexString(packet1));
p.add(getBufferFromHexString(packet2));
assert.ok(gotData);
@@ -102,25 +102,25 @@ module.exports = {
var p = new Parser();
var message = 'Hello';
var packet = '89 FE ' + pack(4, message.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68'));
var gotPing = false;
p.on('ping', function(data) {
gotPing = true;
assert.equal(message, data);
});
p.add(getBufferFromHexString(packet));
assert.ok(gotPing);
},
'can parse a ping with no data': function() {
var p = new Parser();
var packet = '89 00';
var gotPing = false;
p.on('ping', function(data) {
gotPing = true;
});
p.add(getBufferFromHexString(packet));
assert.ok(gotPing);
},
@@ -128,16 +128,16 @@ module.exports = {
var p = new Parser();
var message = 'A';
for (var i = 0; i < 300; ++i) message += (i % 5).toString();
var msgpiece1 = message.substr(0, 150);
var packet1 = '01 FE ' + pack(4, msgpiece1.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece1, '34 83 a8 68'));
var pingMessage = 'Hello';
var pingPacket = '89 FE ' + pack(4, pingMessage.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(pingMessage, '34 83 a8 68'));
var msgpiece2 = message.substr(150);
var packet2 = '80 FE ' + pack(4, msgpiece2.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece2, '34 83 a8 68'));
var gotData = false;
p.on('data', function(data) {
gotData = true;
@@ -148,7 +148,7 @@ module.exports = {
gotPing = true;
assert.equal(pingMessage, data);
});
p.add(getBufferFromHexString(packet1));
p.add(getBufferFromHexString(pingPacket));
p.add(getBufferFromHexString(packet2));
@@ -159,16 +159,16 @@ module.exports = {
var p = new Parser();
var message = 'A';
for (var i = 0; i < 300; ++i) message += (i % 5).toString();
var msgpiece1 = message.substr(0, 150);
var packet1 = '01 FE ' + pack(4, msgpiece1.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece1, '34 83 a8 68'));
var pingMessage = 'Hello';
var pingPacket = '89 FE ' + pack(4, pingMessage.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(pingMessage, '34 83 a8 68'));
var msgpiece2 = message.substr(150);
var packet2 = '80 FE ' + pack(4, msgpiece2.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece2, '34 83 a8 68'));
var gotData = false;
p.on('data', function(data) {
gotData = true;
@@ -179,7 +179,7 @@ module.exports = {
gotPing = true;
assert.equal(pingMessage, data);
});
var buffers = [];
buffers = buffers.concat(splitBuffer(getBufferFromHexString(packet1)));
buffers = buffers.concat(splitBuffer(getBufferFromHexString(pingPacket)));
@@ -195,7 +195,7 @@ module.exports = {
var length = 100;
var message = new Buffer(length);
for (var i = 0; i < length; ++i) message[i] = i % 256;
var originalMessage = getHexStringFromBuffer(message);
var originalMessage = getHexStringFromBuffer(message);
var packet = '82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68'));
var gotData = false;
@@ -203,7 +203,7 @@ module.exports = {
gotData = true;
assert.equal(originalMessage, getHexStringFromBuffer(data));
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
@@ -212,7 +212,7 @@ module.exports = {
var length = 256;
var message = new Buffer(length);
for (var i = 0; i < length; ++i) message[i] = i % 256;
var originalMessage = getHexStringFromBuffer(message);
var originalMessage = getHexStringFromBuffer(message);
var packet = '82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68'));
var gotData = false;
@@ -220,7 +220,7 @@ module.exports = {
gotData = true;
assert.equal(originalMessage, getHexStringFromBuffer(data));
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
@@ -229,7 +229,7 @@ module.exports = {
var length = 200 * 1024;
var message = new Buffer(length);
for (var i = 0; i < length; ++i) message[i] = i % 256;
var originalMessage = getHexStringFromBuffer(message);
var originalMessage = getHexStringFromBuffer(message);
var packet = '82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68'));
var gotData = false;
@@ -237,7 +237,7 @@ module.exports = {
gotData = true;
assert.equal(originalMessage, getHexStringFromBuffer(data));
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},
@@ -246,7 +246,7 @@ module.exports = {
var length = 200 * 1024;
var message = new Buffer(length);
for (var i = 0; i < length; ++i) message[i] = i % 256;
var originalMessage = getHexStringFromBuffer(message);
var originalMessage = getHexStringFromBuffer(message);
var packet = '82 ' + getHybiLengthAsHexString(length, false) + ' ' + getHexStringFromBuffer(message);
var gotData = false;
@@ -254,7 +254,7 @@ module.exports = {
gotData = true;
assert.equal(originalMessage, getHexStringFromBuffer(data));
});
p.add(getBufferFromHexString(packet));
assert.ok(gotData);
},

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
* Test dependencies.
*/
var sio = require('socket.io')
var sio = require('../')
, should = require('./common')
, HTTPClient = should.HTTPClient
, parser = sio.parser
@@ -220,7 +220,12 @@ module.exports = {
done();
});
cl.get('/socket.io/{protocol}/xhr-polling/' + sid + '/?disconnect');
// with the new http bits in node 0.5, there's no guarantee that
// the previous request is actually dispatched (and received) before the following
// reset call is sent. to not waste more time on a workaround, a timeout is added.
setTimeout(function() {
cl.get('/socket.io/{protocol}/xhr-polling/' + sid + '/?disconnect');
}, 500);
});
});
},
@@ -284,6 +289,40 @@ module.exports = {
});
},
'test that connection close does not mean disconnect': function (done) {
var cl = client(++ports)
, io = create(cl)
, sid
, end
, disconnected = false
io.configure(function () {
io.set('polling duration', .2);
io.set('close timeout', .5);
});
io.sockets.on('connection', function (client) {
end = function () {
cl.end();
console.log('ending');
client.on('disconnect', function () {
disconnected = true;
});
}
});
cl.handshake(function (sid) {
cl.get('/socket.io/{protocol}/xhr-polling/' + sid);
setTimeout(end, 30);
setTimeout(function () {
console.log('finished');
disconnected.should.be.false;
io.server.close();
done();
}, 100);
});
},
'test sending back data': function (done) {
var cl = client(++ports)
, io = create(cl);
@@ -763,7 +802,7 @@ module.exports = {
var cl = client(++ports)
, io = create(cl)
, messages = 0;
io.configure(function () {
io.set('polling duration', 0);
io.set('close timeout', .1);
@@ -1312,7 +1351,7 @@ module.exports = {
msgs.should.have.length(1);
msgs[0].should.eql({
type: 'ack'
, ackId: 1
, ackId: '1'
, endpoint: ''
, args: []
});
@@ -2647,8 +2686,8 @@ module.exports = {
}, function (res, packs) {
var headers = res.headers;
headers['access-control-allow-origin'].should.equal('*');
should.strictEqual(headers['access-control-allow-credentials'], undefined);
headers['access-control-allow-origin'].should.equal('http://localhost:3500');
headers['access-control-allow-credentials'].should.equal('true');
packs.should.have.length(1);
packs[0].type.should.eql('message');
@@ -2664,7 +2703,7 @@ module.exports = {
}
}, function (res, data) {
var headers = res.headers;
headers['access-control-allow-origin'].should.equal('*');
headers['access-control-allow-origin'].should.equal('http://localhost:3500');
headers['access-control-allow-credentials'].should.equal('true');
data.should.equal('1');
@@ -2746,7 +2785,7 @@ module.exports = {
}
);
});
});
});
}