Compare commits

...

178 Commits

Author SHA1 Message Date
Guillermo Rauch
4a0091b25a Release 1.2.0 2014-10-27 15:54:57 -07:00
Guillermo Rauch
a1bf85b57f package: bump socket.io-parser 2014-10-27 11:52:09 -07:00
Guillermo Rauch
62ad812ee5 package: use latest socket.io-client 2014-10-27 11:51:03 -07:00
Guillermo Rauch
9ae8ed6929 package: bump adapter 2014-10-27 11:46:44 -07:00
Guillermo Rauch
4a11c16cc2 package: bump socket.io-client 2014-10-27 11:09:44 -07:00
Guillermo Rauch
b88a758857 package: bump engine.io 2014-10-27 07:47:51 -07:00
Guillermo Rauch
3352d1d726 Merge branch 'master' of github.com:Automattic/socket.io 2014-10-13 08:52:46 -07:00
Guillermo Rauch
e68557fab6 downloads badge 2014-10-13 08:52:36 -07:00
Tony Kovanen
da358084f0 Merge pull request #1773 from AjayMT/master
Fix usage example for Server#close.
2014-09-26 01:13:18 +03:00
Tony Kovanen
1b4f6a5324 Merge pull request #1777 from akamensky/dynamic-cors
Dynamic cors
2014-09-22 13:38:14 -06:00
Tony Kovanen
99346eddc5 Merge pull request #1788 from jamesanthonyferguson/patch-1
Change grammar issues in the chat/README.md
2014-09-22 12:42:59 -06:00
Tony Kovanen
051ffa0440 Merge pull request #1626 from thanpolas/patch-1
http.Server is a constructor
2014-09-22 12:42:10 -06:00
Tony Kovanen
fa4fa3365a Merge pull request #1690 from rase-/fix/resource-option-bc
Fix resource option BC with the set function
2014-09-22 12:27:35 -06:00
Tony Kovanen
bafa184c6b Merge pull request #1792 from rase-/add/autopruning-test
Add room autopruning test
2014-09-22 12:25:23 -06:00
Tony Kovanen
e3149d5833 Bump adapter version. 2014-09-20 11:12:58 -06:00
Tony Kovanen
ae9d5277a9 Add test to check that empty rooms are autopruned. 2014-09-20 11:12:26 -06:00
James Ferguson
2e440722a6 Change grammar issues in the chat/README.md
Added a few periods and commas which were missing. Also added the word each to clarify how multiple users each enter a unique username.
Very minor edit. No source code changed.
2014-09-18 21:41:28 -07:00
Tony Kovanen
3fe6d4e8ec Merge pull request #1784 from matthewcanty/patch-1
Change "there're" to "there are"
2014-09-17 07:41:46 -06:00
Matthew Canty
3b93c1c562 Change "there're" to "there are"
Not a commonly used contraction and looks a bit odd.
2014-09-17 14:01:01 +01:00
akamensky
e89f82a9b0 Added Server#origins(v:Function) description for dynamic CORS 2014-09-12 11:32:20 +08:00
akamensky
1b90ae2587 Added test coverage for Server#origins(function) for dynamic CORS 2014-09-12 11:13:51 +08:00
akamensky
9658e32e7a Added optional Server#origins(function) for dynamic CORS 2014-09-12 10:53:14 +08:00
Tony Kovanen
99d76664aa Merge pull request #1766 from BrianGeppert/master
package: fix main file for example application 'chat'.
2014-09-11 18:05:58 +03:00
Ajay MT
23eefa527a Fix usage example for Server#close. 2014-09-10 18:11:56 +05:30
Brian Geppert
b49b35b26f package: fix main file for example application 'chat'. 2014-09-04 12:10:43 -05:00
Guillermo Rauch
16483375a7 Release 1.1.0 2014-09-04 12:06:06 +02:00
Guillermo Rauch
ec305bd8df examples: minor fix of escaping 2014-09-04 11:44:02 +02:00
Guillermo Rauch
af07a1c649 package: bump engine.io 2014-09-04 01:57:58 +02:00
Tony Kovanen
5863903d44 Merge pull request #1729 from anupbishnoi/patch-1
Take "" and "/" as equivalent namespaces on server
2014-08-20 11:27:46 +03:00
Anup Bishnoi
f56d4acce6 testing for equivalence of namespaces starting with / or without 2014-08-19 22:19:50 +00:00
Anup Bishnoi
8ea37b7351 Update index.js 2014-08-19 16:17:45 -04:00
Anup Bishnoi
b3cb18d910 Added relevant tests
"" and "/" namespaces are checked for equivalence on server and client
2014-08-18 22:47:06 -04:00
Anup Bishnoi
0e41561d56 Take "" and "/" as equivalent namespaces on server
On server, `.of(name)` should use the same key in `.nsps` object for "" and "/"

Important to use `String(name)` and `===` to keep out keys that don't cast to ""
2014-08-18 22:38:47 -04:00
Guillermo Rauch
83709e9487 Merge pull request #1714 from PeterDaveHello/patch-2
Use svg instead of png to get better image quality
2014-08-12 15:47:12 -07:00
Guillermo Rauch
6f4051aaa7 Merge pull request #1713 from PeterDaveHello/patch-1
make CI build faster
2014-08-12 15:45:58 -07:00
Peter Dave Hello
87bf6910b5 Use svg instead of png to get better image quality 2014-08-12 10:56:04 +08:00
Peter Dave Hello
8946b4ed4c make CI build faster 2014-08-12 10:51:01 +08:00
Guillermo Rauch
a40068b5f3 Merge pull request #1688 from fdellabetta/server_side_namespace
client cannot connect to non-existing namespaces
2014-08-01 13:45:32 +01:00
Guillermo Rauch
9e29ec9b2b Merge pull request #1700 from rase-/fix/rooms
Fix splice arguments and `socket.rooms` value update in `socket.leaveAll`
2014-08-01 13:45:01 +01:00
Tony Kovanen
624e7cb14f Fix splice arguments and socket.rooms value update in socket.leaveAll.
Hat tip @Marreck
2014-08-01 13:20:18 +02:00
Tony Kovanen
b4954d767a Take the instance stored path value into account when attaching to eio if no option specified to attach directly 2014-07-23 19:58:44 +03:00
Filippo Della Betta
f6eb53f5e1 client cannot connect to non-existing namespaces 2014-07-22 13:58:13 +02:00
Guillermo Rauch
9c80317574 Merge pull request #1685 from rase-/fix/remote-address-in-handshake-obj
Fix remote address in handshake obj
2014-07-18 19:47:26 -07:00
Tony Kovanen
d163d891ef Bump engine.io version to get the cached IP address 2014-07-19 04:49:51 +03:00
Tony Kovanen
54726105cb Fixed handshake object address property and made the test case more strict. 2014-07-19 04:43:03 +03:00
Guillermo Rauch
3d9e52cf93 Merge branch 'master' of github.com:Automattic/socket.io 2014-07-17 12:20:17 -07:00
Guillermo Rauch
ad74f2ff88 package: bump engine.io 2014-07-17 12:17:46 -07:00
Guillermo Rauch
cf1c1273b3 Merge pull request #1682 from kevin-roark/fix/disconnect-connectbuffer-crash
Fixed the failing test where server crashes on disconnect involving connectBuffer
2014-07-16 10:58:54 -07:00
Kevin Roark
1f43c4abb5 Fixed the failing test where server crashes on disconnect involving connectBuffer
Source of bug: after connection to nsp '/', the socket's connectBuffer
was being deleted. On attempt to reconnect to a different namespace,
the connect buffer was deleted and we attempted to push to it. Instead
of the deleting the connect buffer, it is now emptied.
2014-07-16 08:35:16 -07:00
Guillermo Rauch
d6e6e8a2f8 Merge pull request #1673 from bryanburgers/patch-1
Fix repo in package.json
2014-07-15 18:25:59 -07:00
Guillermo Rauch
fbd36b613d npmignore: ignore .gitignore (fixes #1607) 2014-07-15 10:55:34 -07:00
Guillermo Rauch
480b1a05bd test: added failing case for socket.disconnect and nsps 2014-07-15 10:52:23 -07:00
Bryan Burgers
ef729b72b4 Fix repo in package.json 2014-07-09 07:28:45 -05:00
Thanasis Polychronakis
63e197083b update README http ctor to createServer() 2014-07-01 10:41:53 +03:00
Guillermo Rauch
968e94e42b Merge pull request #1655 from ysmood/fix_etag_header
We should use the standard http protocol to handler the etag header
2014-06-30 23:32:23 -07:00
Guillermo Rauch
c18ed5fd4d Merge pull request #1646 from narcisoguillen/close_sio
Close sio
2014-06-30 19:10:26 -07:00
Narciso Guillen
1f7da938bd Improve Close documentation 2014-06-30 15:57:21 -05:00
Narciso Guillen
4b89bce182 use ephemeral ports 2014-06-30 15:49:08 -05:00
Yad Smood
8c19eef07a fix: We should use the standard http protocol to handler the etag
header.
2014-06-29 21:42:57 +08:00
Guillermo Rauch
662b30669b Merge pull request #1653 from acusti/patch-1
Override default browser font-family for inputs
2014-06-28 10:55:22 -07:00
Andrew Patton
001373ee17 Override default browser font-family for inputs
For consistent typography, explicitly declare font-family stack for `input` in addition to `html` (in Chrome and Safari on mac, the input will otherwise use default font for such elements, like Lucida Grande)
2014-06-28 13:14:33 -04:00
Guillermo Rauch
246f3bb5c3 Merge pull request #1648 from kevin-roark/update/has-binary-data
update has-binary-data to 1.0.3
2014-06-23 20:20:39 -07:00
Kevin Roark
68d06ec94c update has-binary-data to 1.0.3 2014-06-23 20:19:26 -07:00
Narciso Guillen
a1feca1bd3 Add close specs 2014-06-23 21:03:31 -05:00
Narciso Guillen
968105a239 Add ability to stop the http server even if not created inside socket.io 2014-06-23 21:03:12 -05:00
Narciso Guillen
2e8e26613a Update README 2014-06-23 20:02:39 -05:00
Narciso Guillen
fbdb94d146 make sure server gets close 2014-06-23 19:55:02 -05:00
Tony Kovanen
55572122f3 Merge pull request #1642 from rase-/add/test
Duplicate events test for `reconnect_failed`
2014-06-21 17:28:37 +03:00
Tony Kovanen
a1170a3aa6 Bump client 2014-06-21 17:26:55 +03:00
Tony Kovanen
0954301d7e Add test case for checking that reconnect_failed is fired only once upon failure 2014-06-21 17:14:15 +03:00
Guillermo Rauch
328a9df8eb package: bump socket.io-parser for component-emitter dep fix
cc @davglass @reid
2014-06-20 16:57:54 -07:00
Guillermo Rauch
d99e30fca7 Release 1.0.6 2014-06-19 14:57:50 -07:00
Guillermo Rauch
561dd6fd79 package: bump engine.io for utf8 fix (fixes #1622) 2014-06-19 14:51:37 -07:00
Guillermo Rauch
e9e2a91cea package: bump socket.io-client 2014-06-19 08:05:38 -07:00
Guillermo Rauch
8a3a111a7f Merge pull request #1635 from rase-/add/test
Test for duplicate events on manual reconnect
2014-06-18 15:54:23 -07:00
Tony Kovanen
bd87e4dc35 Bump socket.io-client to latest commit so that duplicate events test passes 2014-06-19 01:52:34 +03:00
Tony Kovanen
71c253e992 Added test for duplicate events after manual reconnects 2014-06-19 01:49:00 +03:00
Guillermo Rauch
a5cf4f57a0 Release 1.0.5 2014-06-17 18:14:44 -07:00
Guillermo Rauch
a079cbc7f9 client: fixes #1632 2014-06-17 18:07:30 -07:00
Guillermo Rauch
14a9fdb64f package: bump engine.io 2014-06-16 08:36:01 -07:00
Thanasis Polychronakis
55fb100fc0 http.Server is a constructor
...and thus requires the `new` keyword
2014-06-14 13:52:36 +03:00
Guillermo Rauch
6159df3937 fixed client 2014-06-13 13:04:50 -07:00
Guillermo Rauch
6f7bab5dfd Merge pull request #1578 from kevin-roark/add/emit-buffer-test
added the client emit-buffer test
2014-06-13 10:10:40 -07:00
Guillermo Rauch
7d2b44e176 index: fix typo [thanks @yanatan16] 2014-06-11 10:42:48 -07:00
Tony Kovanen
0b5fdf995a Merge pull request #1603 from nkzawa/patch-2
Add removeListener to blacklisted events
2014-06-08 14:40:25 +03:00
Naoyuki Kanezawa
a66bea5b33 add removeListener to blacklisted events 2014-06-08 20:34:50 +09:00
Guillermo Rauch
a1a88aaaaf Merge pull request #1600 from poldridge/master
Update index.js
2014-06-06 22:36:19 -07:00
poldridge
3f817c3a18 Update index.js
Added missing hasOwnProperty check. socket.io breaks without it when Object.prototype has been extended.
2014-06-06 22:08:58 -07:00
Guillermo Rauch
99bbd74d14 Merge pull request #1582 from kevin-roark/add/clearer-example-instructions
Add/clearer example instructions
2014-06-02 20:44:34 -07:00
Kevin Roark
398511ddee Merge branch 'upstream' into add/clearer-example-instructions 2014-06-02 20:28:42 -07:00
Kevin Roark
fdf7937815 clearer instructions to install chat example 2014-06-02 20:28:19 -07:00
Guillermo Rauch
475909e642 Release 1.0.4 2014-06-02 20:08:33 -07:00
Guillermo Rauch
95acec8b94 package: bump socket.io-client 2014-06-02 20:07:07 -07:00
Kevin Roark
5812ddf2b0 added the client emit-buffer test 2014-06-01 23:20:42 -07:00
Guillermo Rauch
1bbc3951bd Release 1.0.3 2014-05-31 18:34:50 -07:00
Guillermo Rauch
039eed2c2a package: bump socket.io-client 2014-05-31 09:53:25 -07:00
Guillermo Rauch
6de022b180 Merge pull request #1565 from kevin-roark/add/binary-ack
Add/binary ack
2014-05-31 09:50:19 -07:00
Guillermo Rauch
a06331d29f travis fix 2014-05-30 21:37:22 -07:00
Guillermo Rauch
e639685370 fix travis 2014-05-30 21:23:55 -07:00
Guillermo Rauch
1f2e681ce2 package: bump socket.io-parser for binary ack fix 2014-05-30 21:11:57 -07:00
Kevin Roark
397944fcbe big file tests 2014-05-30 20:40:44 -07:00
Kevin Roark
27dada65b9 distinction between ACK and BINARY_ACK 2014-05-30 18:42:23 -07:00
Guillermo Rauch
99f1ac9aae Merge pull request #1563 from rase-/fix/no-disconnect-fired-for-nsp
Fix namespace iterator in disconnect
2014-05-30 16:40:59 -07:00
Tony Kovanen
ee8d0fbae0 Fix namespace iterator in disconnect 2014-05-31 02:25:28 +03:00
Guillermo Rauch
8e08a6d419 Merge pull request #1562 from rase-/add/utf8-tests
Add test case for emitting multibyte chars
2014-05-30 15:48:34 -07:00
Tony Kovanen
318ae87f50 Add test case for emitting multibyte chars 2014-05-31 01:45:31 +03:00
Guillermo Rauch
2c1b61148d Merge branch 'master' of github.com:automattic/socket.io 2014-05-30 14:14:12 -07:00
Guillermo Rauch
507054c0a8 package: bump engine.io for utf8 binary fix 2014-05-30 14:09:54 -07:00
Tony Kovanen
dfceb006d7 Merge pull request #1554 from grant/master
Fix xss vulnerability in example chat app
2014-05-30 12:15:12 +03:00
Grant Timmerman
4d83456f74 Fix xss vulnerability in example chat app 2014-05-30 02:03:33 -07:00
Tony Kovanen
201aad83b1 Merge pull request #1540 from grant/master
Make chat example wrap long words (no overflow)
2014-05-30 12:02:15 +03:00
Grant Timmerman
72eb61d01f Make chat example wrap long words (no overflow) 2014-05-30 01:44:27 -07:00
Tony Kovanen
163a2a696e Merge pull request #1543 from mohnish/patch-1
Remove obsolete message from README file
2014-05-29 21:33:36 +03:00
Guillermo Rauch
199a479ebc Merge pull request #1545 from overra/patch-1
Use cleanInput() on incoming messages
2014-05-28 20:47:20 -07:00
Guillermo Rauch
d383ff9662 Merge pull request #1546 from hiddenmin/patch-1
Update Readme.md
2014-05-28 19:42:39 -07:00
Amin Cheloh
416b550189 Update Readme.md
socket.io-adapter link
2014-05-29 09:41:37 +07:00
Adam Snodgrass
536b338a01 Use cleanInput() on incoming messages
This prevents XSS if one were to send messages using socket.io from the console.
2014-05-28 20:35:24 -05:00
Mohnish Thallavajhula
a06ae10895 Remove obsolete message from README file 2014-05-28 17:10:50 -07:00
Guillermo Rauch
35a85084b1 Release 1.0.2 2014-05-28 13:24:59 -07:00
Guillermo Rauch
0c2b44a846 package: bump parser for windows fix 2014-05-28 13:23:51 -07:00
Guillermo Rauch
0f6ee2dbd9 travis 2014-05-28 12:56:10 -07:00
Guillermo Rauch
68ac0d6d24 Release 1.0.1 2014-05-28 10:32:31 -07:00
Guillermo Rauch
00ef9ca652 Release 1.0.0 2014-05-28 10:19:24 -07:00
Guillermo Rauch
2febbce87d Merge pull request #1530 from kevin-roark/update/has-binary-data
bump has-binary-data
2014-05-24 15:19:48 -07:00
Kevin Roark
31c45862cb bump has-binary-data 2014-05-24 14:14:59 -05:00
Guillermo Rauch
809e2bc3f8 Merge pull request #1529 from rase-/add/bc
Added socket.handshake BC object
2014-05-24 11:08:00 -07:00
Tony Kovanen
10adcb089e Added socket.handshake BC object 2014-05-24 17:02:47 +03:00
Guillermo Rauch
5bc75ea944 Release 1.0.0-pre5 2014-05-22 09:35:32 -07:00
Guillermo Rauch
cd4f6ad5e9 package: bump socket.io-client for parser fixes 2014-05-22 09:32:42 -07:00
Guillermo Rauch
54e6c79014 package: bump engine.io 2014-05-22 09:25:58 -07:00
Guillermo Rauch
237b234cab Release 1.0.0-pre4 2014-05-19 16:02:54 -07:00
Guillermo Rauch
547440605d package: bump client 2014-05-19 16:02:31 -07:00
Guillermo Rauch
d763c8b6ea Release 1.0.0-pre3 2014-05-17 15:40:40 -07:00
Guillermo Rauch
5d210ac46c package: bump parser 2014-05-17 14:02:57 -07:00
Guillermo Rauch
ea89e520bc package: bump engine.io 2014-05-16 16:57:41 -07:00
Guillermo Rauch
c8bf064b10 Merge pull request #1513 from hallucynogenyc/patch-1
Update for new npm check
2014-05-06 10:15:33 -04:00
hallucynogenyc
08fe191211 Update for new npm check
Npm will now throw a warning when installing a package:

npm WARN package.json socket.io@1.0.0-pre2 No repository field.

If the repository field is not present.
2014-05-06 16:14:50 +02:00
Guillermo Rauch
0842729c1f test: temporarily removing parser test 2014-04-28 11:16:59 -07:00
Guillermo Rauch
9720c76d10 Release 1.0.0-pre2 2014-04-27 19:40:33 -07:00
Guillermo Rauch
0f127d2b7d package: bump engine.io 2014-04-27 19:23:07 -07:00
Guillermo Rauch
e87e9e18e1 package: bump parser 2014-04-27 18:54:53 -07:00
Guillermo Rauch
46351d38b8 Merge pull request #1489 from kevin-roark/add/protocol-check
added test that server and client using same protocol
2014-04-14 13:11:04 -07:00
Kevin Roark
ce68fb3105 Merge branch 'upstream' into add/protocol-check 2014-04-14 12:43:01 -04:00
Guillermo Rauch
94905500e4 Merge pull request #1467 from rase-/add/set-backwards-compatibility
Added backwards compatible settability of engine.io maxHttpBufferSize
2014-04-13 12:25:36 -07:00
Tony Kovanen
f830899e39 Added backwards compatible settability of engine.io maxHttpBufferSize
Updated readme
2014-04-12 12:02:52 +03:00
Guillermo Rauch
3444f017bc Merge pull request #1492 from kevin-roark/add/query-test
Added a test to check access to client query params
2014-04-11 10:57:04 -07:00
Kevin Roark
0588dc0fc4 Added a test to check access to client query params
It fails with the current upstream client! There is a pending PR to
make this test pass though.
2014-04-11 13:19:19 -04:00
Guillermo Rauch
57425ab1dd Merge pull request #1485 from rase-/add/origins
Added support for setting allowed origins
2014-04-11 09:46:37 -07:00
Tony Kovanen
463d7a16a1 Moved the origins checking callback outside the origins getter/setter function. 2014-04-11 19:39:10 +03:00
Tony Kovanen
5d74847123 Updated README to include origins 2014-04-11 01:29:37 +03:00
Kevin Roark
f8b4d87331 added test that server and client using same protocol 2014-04-10 14:45:32 -04:00
Tony Kovanen
e9928b2b1d Switched to async allowRequest callback in engine.io for setting the allowed origins 2014-04-10 21:02:20 +03:00
Tony Kovanen
d33553a4bd Added support for setting allowed origins 2014-04-09 22:34:53 +03:00
Guillermo Rauch
45a98970d7 added information about logging 2014-03-28 11:51:54 -03:00
Guillermo Rauch
0b4e4f6a67 Merge pull request #1464 from rase-/add/set-backwards-compatibility
Set function for BC
2014-03-25 20:09:16 -03:00
Tony Kovanen
656047536a The set function in server can be used to set some attributes for backwards compatibility 2014-03-26 00:04:22 +02:00
Guillermo Rauch
97b7ab4fe2 Merge pull request #1462 from nicolagreco/patch-1
Mistake in callback call 'done' instead of 'next' in docs
2014-03-24 22:38:02 -03:00
Nicola Greco
6a435ce677 Mistake in callback call 'done' instead of 'next' in docs 2014-03-25 01:02:46 +00:00
Guillermo Rauch
6aa553b211 Merge branch 'master' of github.com:LearnBoost/socket.io 2014-03-24 14:44:00 -03:00
Guillermo Rauch
024af23b2c package: bump client 2014-03-24 14:43:37 -03:00
Guillermo Rauch
b50d9f8f5d Merge pull request #1443 from kevin-roark/add/simple-tests
added some new tests, including binary with acks
2014-03-24 14:21:19 -03:00
Kevin Roark
874c194210 Merge branch 'upstream' into add/simple-tests
Conflicts:
	package.json
2014-03-24 13:03:43 -04:00
Guillermo Rauch
f537560bcc package: bump socket.io-parser 2014-03-18 18:28:49 -03:00
Guillermo Rauch
7197d6a29d rebuild 2014-03-18 17:16:38 -03:00
Guillermo Rauch
8dba96511d package: rollback socket.io-parser to fix acks 2014-03-18 16:45:48 -03:00
Guillermo Rauch
f8d1d33dfa Merge branch 'master' of github.com:LearnBoost/socket.io
Conflicts:
	package.json
2014-03-18 16:34:49 -03:00
Guillermo Rauch
736106a9e7 package: bump engine.io 2014-03-18 16:31:22 -03:00
Guillermo Rauch
f5a8ac293a Merge pull request #1452 from kevin-roark/update/parser-dependency
updated parser dependency
2014-03-15 19:35:35 -02:00
Kevin Roark
afc83ad65a Merge branch 'upstream' into add/simple-tests
Conflicts:
	package.json
2014-03-15 17:32:27 -04:00
Kevin Roark
b5f90923a2 updated parser dependency 2014-03-15 17:30:47 -04:00
Guillermo Rauch
c574f5f959 Merge pull request #1451 from elisee/patch-1
Fix // … to be /* … */ in README.md
2014-03-15 17:57:01 -02:00
elisee
ba339cc460 Fix // … to be /* … */ 2014-03-15 20:25:00 +01:00
Guillermo Rauch
aee4dd9a6d package: bump expect.js 2014-03-15 10:39:21 -03:00
Kevin Roark
7d4aa670ad bumped parser dependency 2014-03-13 10:49:31 -04:00
Kevin Roark
620f94a007 Merge branch 'upstream' into add/simple-tests
Conflicts:
	package.json
2014-03-12 20:33:01 -04:00
Kevin Roark
4823d20cf1 Merge branch 'upstream' into add/simple-tests
Conflicts:
	package.json
2014-03-08 20:58:41 -05:00
Kevin Roark
612d35194f updated parser dependency 2014-03-06 18:41:43 -05:00
Kevin Roark
a5ff1d854e added some new tests, including binary with acks 2014-03-06 16:58:21 -05:00
15 changed files with 175129 additions and 173 deletions

View File

@@ -1,3 +1,4 @@
support
test
examples
.gitignore

View File

@@ -4,6 +4,9 @@ node_js:
- "0.10"
- "0.11"
git:
depth: 1
matrix:
fast_finish: true
allow_failures:

View File

@@ -1,4 +1,122 @@
1.2.0 / 2014-10-27
==================
* package: bump `engine.io`
* downloads badge
* add test to check that empty rooms are autopruned
* added Server#origins(v:Function) description for dynamic CORS
* added test coverage for Server#origins(function) for dynamic CORS
* added optional Server#origins(function) for dynamic CORS
* fix usage example for Server#close
* package: fix main file for example application 'chat'
* package: bump `socket.io-parser`
* update README http ctor to createServer()
* bump adapter with a lot of fixes for room bookkeeping
1.1.0 / 2014-09-04
==================
* examples: minor fix of escaping
* testing for equivalence of namespaces starting with / or without
* update index.js
* added relevant tests
* take "" and "/" as equivalent namespaces on server
* use svg instead of png to get better image quality in readme
* make CI build faster
* fix splice arguments and `socket.rooms` value update in `socket.leaveAll`.
* client cannot connect to non-existing namespaces
* bump engine.io version to get the cached IP address
* fixed handshake object address property and made the test case more strict.
* package: bump `engine.io`
* fixed the failing test where server crashes on disconnect involving connectBuffer
* npmignore: ignore `.gitignore` (fixes #1607)
* test: added failing case for `socket.disconnect` and nsps
* fix repo in package.json
* improve Close documentation
* use ephemeral ports
* fix: We should use the standard http protocol to handler the etag header.
* override default browser font-family for inputs
* update has-binary-data to 1.0.3
* add close specs
* add ability to stop the http server even if not created inside socket.io
* make sure server gets close
* Add test case for checking that reconnect_failed is fired only once upon failure
* package: bump `socket.io-parser` for `component-emitter` dep fix
1.0.6 / 2014-06-19
==================
* package: bump `socket.io-client`
1.0.5 / 2014-06-16
==================
* package: bump `engine.io` to fix jsonp `\n` bug and CORS warnings
* index: fix typo [yanatan16]
* add `removeListener` to blacklisted events
* examples: clearer instructions to install chat example
* index: fix namespace `connectBuffer` issue
1.0.4 / 2014-06-02
==================
* package: bump socket.io-client
1.0.3 / 2014-05-31
==================
* package: bump `socket.io-client`
* package: bump `socket.io-parser` for binary ACK fix
* package: bump `engine.io` for binary UTF8 fix
* example: fix XSS in chat example
1.0.2 / 2014-05-28
==================
* package: bump `socket.io-parser` for windows fix
1.0.1 / 2014-05-28
==================
* bump due to bad npm tag
1.0.0 / 2014-05-28
==================
* stable release
1.0.0-pre5 / 2014-05-22
=======================
* package: bump `socket.io-client` for parser fixes
* package: bump `engine.io`
1.0.0-pre4 / 2014-05-19
=======================
* package: bump client
1.0.0-pre3 / 2014-05-17
=======================
* package: bump parser
* package: bump engine.io
1.0.0-pre2 / 2014-04-27
=======================
* package: bump `engine.io`
* added backwards compatible of engine.io maxHttpBufferSize
* added test that server and client using same protocol
* added support for setting allowed origins
* added information about logging
* the set function in server can be used to set some attributes for BC
* fix error in callback call 'done' instead of 'next' in docs
* package: bump `socket.io-parser`
* package: bump `expect.js`
* added some new tests, including binary with acks
1.0.0-pre / 2014-03-14
======================

View File

@@ -1,12 +1,9 @@
### This Readme corresponds to the upcoming 1.0 release. Please refer to http://socket.io for the current 0.9.x documentation.
<hr />
# socket.io
[![Build Status](https://secure.travis-ci.org/LearnBoost/socket.io.png)](http://travis-ci.org/LearnBoost/socket.io)
[![NPM version](https://badge.fury.io/js/socket.io.png)](http://badge.fury.io/js/socket.io)
[![Build Status](https://secure.travis-ci.org/Automattic/socket.io.svg)](http://travis-ci.org/Automattic/socket.io)
[![NPM version](https://badge.fury.io/js/socket.io.svg)](http://badge.fury.io/js/socket.io)
![Downloads](http://img.shields.io/npm/dm/socket.io.svg)
## How to use
@@ -14,7 +11,7 @@ The following example attaches socket.io to a plain Node.JS
HTTP server listening on port `3000`.
```js
var server = require('http').Server();
var server = require('http').createServer();
var io = require('socket.io')(server);
io.on('connection', function(socket){
socket.on('event', function(data){});
@@ -31,7 +28,7 @@ io.on('connection', function(socket){});
io.listen(3000);
```
### In conjunction with `Express`
### In conjunction with Express
Starting with **3.0**, express applications have become request handler
functions that you pass to `http` or `http` `Server` instances. You need
@@ -40,22 +37,22 @@ function.
```js
var app = require('express')();
var server = require('http').Server(app);
var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(){ // … });
io.on('connection', function(){ /* … */ });
server.listen(3000);
```
### In conjunction with `Koa`
### In conjunction with Koa
Like Express.JS, Koa works by exposing an application as a request
handler function, but only by calling the `callback` method.
```js
var app = require('koa')();
var server = require('http').Server(app.callback());
var server = require('http').createServer(app.callback());
var io = require('socket.io')(server);
io.on('connection', function(){ // … });
io.on('connection', function(){ /* … */ });
server.listen(3000);
```
@@ -130,10 +127,26 @@ server.listen(3000);
Sets the adapter `v`. Defaults to an instance of the `Adapter` that
ships with socket.io which is memory based. See
[socket.io-adapter](https://github.com/learnboost/socket.io-adapter).
[socket.io-adapter](https://github.com/Automattic/socket.io-adapter).
If no arguments are supplied this method returns the current value.
### Server#origins(v:String):Server
Sets the allowed origins `v`. Defaults to any origins being allowed.
If no arguments are supplied this method returns the current value.
### Server#origins(v:Function):Server
Sets the allowed origins as dynamic function. Function takes two arguments `origin:String` and `callback(error, success)`, where `success` is a boolean value indicating whether origin is allowed or not.
__Potential drawbacks__:
* in some situations, when it is not possible to determine `origin` it may have value of `*`
* As this function will be executed for every request, it is advised to make this function work as fast as possible
* If `socket.io` is used together with `Express`, the CORS headers will be affected only for `socket.io` requests. For Express can use [cors](https://github.com/troygoode/node-cors/)
### Server#sockets:Namespace
The default (`/`) namespace.
@@ -154,7 +167,7 @@ server.listen(3000);
### Server#bind(srv:engine#Server):Server
Advanced use only. Binds the server to a specific engine.io `Server`
Advanced use only. Binds the server to a specific engine.io `Server`
(or compatible API) instance.
### Server#onconnection(socket:engine#Socket):Server
@@ -164,14 +177,14 @@ server.listen(3000);
### Server#of(nsp:String):Namespace
Initializes and retrieves the given `Namespace` by its pathname
Initializes and retrieves the given `Namespace` by its pathname
identifier `nsp`.
If the namespace was already initialized it returns it right away.
### Server#emit
Emits an event to all connected clients. The following two are
Emits an event to all connected clients. The following two are
equivalent:
```js
@@ -182,6 +195,24 @@ server.listen(3000);
For other available methods, see `Namespace` below.
### Server#close
Closes socket server
```js
var Server = require('socket.io');
var PORT = 3030;
var server = require('http').Server();
var io = Server(PORT);
io.close(); // Close current server
server.listen(PORT); // PORT is free to use
io = Server(server);
```
### Server#use
See `Namespace#use` below.
@@ -220,7 +251,7 @@ server.listen(3000);
var io = require('socket.io')();
io.use(function(socket, next){
if (socket.request.headers.cookie) return next();
done(new Error('Authentication error'));
next(new Error('Authentication error'));
});
```
@@ -282,7 +313,7 @@ server.listen(3000);
The mechanics of joining rooms are handled by the `Adapter`
that has been configured (see `Server#adapter` above), defaulting to
[socket.io-adapter](https://github.com/socket.io/socket.io-adapter).
[socket.io-adapter](https://github.com/Automattic/socket.io-adapter).
### Socket#leave(name:String[, fn:Function]):Socket
@@ -293,7 +324,7 @@ server.listen(3000);
The mechanics of leaving rooms are handled by the `Adapter`
that has been configured (see `Server#adapter` above), defaulting to
[socket.io-adapter](https://github.com/socket.io/socket.io-adapter).
[socket.io-adapter](https://github.com/Automattic/socket.io-adapter).
### Socket#to(room:String):Socket
### Socket#in(room:String):Socket
@@ -326,6 +357,18 @@ server.listen(3000);
originated the engine.io connection. Useful for accessing
request headers such as `Cookie` or `User-Agent`.
## Debug / logging
Socket.IO is powered by [debug](http://github.com/visionmedia/debug).
In order to see all the debug output, run your app with the environment variable
`DEBUG` including the desired scope.
To see the output from all of Socket.IO's debugging scopes you can use:
```
DEBUG=socket.io* node myapp
```
## License
MIT

View File

@@ -6,17 +6,20 @@ A simple chat demo for socket.io
## How to use
```
$ cd socket.io
$ npm install
$ cd examples/chat
$ npm install
$ node .
```
And point your browser to `http://localhost:3000`. Optionally specify
And point your browser to `http://localhost:3000`. Optionally, specify
a port by supplying the `PORT` env variable.
## Features
- Multiple users can join a chat room by entering a unique username
- Multiple users can join a chat room by each entering a unique username
on website load.
- Users can type chat messages to the chat room
- Users can type chat messages to the chat room.
- A notification is sent to all users when a user joins or leaves
the chatroom
the chatroom.

View File

@@ -2,7 +2,7 @@
"name": "socket.io-chat",
"version": "0.0.0",
"description": "A simple chat client using socket.io",
"main": "app.js",
"main": "index.js",
"author": "Grant Timmerman",
"private": true,
"license": "BSD",

View File

@@ -30,7 +30,7 @@ $(function() {
if (data.numUsers === 1) {
message += "there's 1 participant";
} else {
message += "there're " + data.numUsers + " participants";
message += "there are " + data.numUsers + " participants";
}
log(message);
}
@@ -70,8 +70,8 @@ $(function() {
// Log a message
function log (message, options) {
var el = '<li class="log">' + message + '</li>';
addMessageElement(el, options);
var $el = $('<li>').addClass('log').text(message);
addMessageElement($el, options);
}
// Adds the visual chat message to the message list
@@ -84,16 +84,17 @@ $(function() {
$typingMessages.remove();
}
var colorStyle = 'style="color:' + getUsernameColor(data.username) + '"';
var usernameDiv = '<span class="username"' + colorStyle + '>' +
data.username + '</span>';
var messageBodyDiv = '<span class="messageBody">' +
data.message + '</span>';
var $usernameDiv = $('<span class="username"/>')
.text(data.username)
.css('color', getUsernameColor(data.username));
var $messageBodyDiv = $('<span class="messageBody">')
.text(data.message);
var typingClass = data.typing ? 'typing' : '';
var messageDiv = '<li class="message ' + typingClass + '">' +
usernameDiv + messageBodyDiv + '</li>';
var $messageDiv = $(messageDiv).data('username', data.username);
var $messageDiv = $('<li class="message"/>')
.data('username', data.username)
.addClass(typingClass)
.append($usernameDiv, $messageBodyDiv);
addMessageElement($messageDiv, options);
}
@@ -145,7 +146,7 @@ $(function() {
// Prevents input from having injected markup
function cleanInput (input) {
return $('<div/>').text(input).html() || input;
return $('<div/>').text(input).text();
}
// Updates the typing event
@@ -228,7 +229,7 @@ $(function() {
socket.on('login', function (data) {
connected = true;
// Display the welcome message
var message = "Welcome to Socket.IO Chat &mdash; ";
var message = "Welcome to Socket.IO Chat ";
log(message, {
prepend: true
});
@@ -262,4 +263,4 @@ $(function() {
socket.on('stop typing', function (data) {
removeChatTyping(data);
});
});
});

View File

@@ -5,6 +5,11 @@
}
html {
font-weight: 300;
-webkit-font-smoothing: antialiased;
}
html, input {
font-family:
"HelveticaNeue-Light",
"Helvetica Neue Light",
@@ -13,8 +18,6 @@ html {
Arial,
"Lucida Grande",
sans-serif;
font-weight: 300;
-webkit-font-smoothing: antialiased;
}
html, body {
@@ -25,6 +28,7 @@ html, body {
ul {
list-style: none;
word-wrap: break-word;
}
/* Pages */
@@ -143,4 +147,4 @@ ul {
position: absolute;
right: 0;
width: 100%;
}
}

View File

@@ -57,6 +57,10 @@ Client.prototype.setup = function(){
Client.prototype.connect = function(name){
debug('connecting to namespace %s', name);
if (!this.server.nsps[name]) {
this.packet({ type: parser.ERROR, nsp: name, data : 'Invalid namespace'});
return;
}
var nsp = this.server.of(name);
if ('/' != name && !this.nsps['/']) {
this.connectBuffer.push(name);
@@ -68,9 +72,9 @@ Client.prototype.connect = function(name){
self.sockets.push(socket);
self.nsps[nsp.name] = socket;
if ('/' == nsp.name) {
if ('/' == nsp.name && self.connectBuffer.length > 0) {
self.connectBuffer.forEach(self.connect, self);
delete self.connectBuffer;
self.connectBuffer = [];
}
});
};
@@ -199,9 +203,10 @@ Client.prototype.onclose = function(reason){
this.destroy();
// `nsps` and `sockets` are cleaned up seamlessly
this.sockets.forEach(function(socket){
var socket;
while (socket = this.sockets.shift()) {
socket.onclose(reason);
});
}
this.decoder.destroy(); // clean up decoder
};

View File

@@ -13,6 +13,7 @@ var Client = require('./client');
var Namespace = require('./namespace');
var Adapter = require('socket.io-adapter');
var debug = require('debug')('socket.io:server');
var url = require('url');
/**
* Module exports.
@@ -45,10 +46,41 @@ function Server(srv, opts){
this.path(opts.path || '/socket.io');
this.serveClient(false !== opts.serveClient);
this.adapter(opts.adapter || Adapter);
this.origins(opts.origins || '*:*');
this.sockets = this.of('/');
if (srv) this.attach(srv, opts);
}
/**
* Server request verification function, that checks for allowed origins
*
* @param {http.IncomingMessage} request
* @param {Function} callback to be called with the result: `fn(err, success)`
*/
Server.prototype.checkRequest = function(req, fn) {
var origin = req.headers.origin || req.headers.referer;
// file:// URLs produce a null Origin which can't be authorized via echo-back
if ('null' == origin) origin = '*';
if (!!origin && typeof(this._origins) == 'function') return this._origins(origin, fn);
if (this._origins.indexOf('*:*') !== -1) return fn(null, true);
if (origin) {
try {
var parts = url.parse(origin);
parts.port = parts.port || 80;
var ok =
~this._origins.indexOf(parts.hostname + ':' + parts.port) ||
~this._origins.indexOf(parts.hostname + ':*') ||
~this._origins.indexOf('*:' + parts.port);
return fn(null, !!ok);
} catch (ex) {
}
}
fn(null, false);
};
/**
* Sets/gets whether client code is being served.
*
@@ -63,13 +95,42 @@ Server.prototype.serveClient = function(v){
return this;
};
/**
* Old settings for backwards compatibility
*/
var oldSettings = {
"transports": "transports",
"heartbeat timeout": "pingTimeout",
"heartbeat interval": "pingInterval",
"destroy buffer size": "maxHttpBufferSize"
};
/**
* Backwards compatiblity.
*
* @api public
*/
Server.prototype.set = function(){
Server.prototype.set = function(key, val){
if ('authorization' == key && val) {
this.use(function(socket, next) {
val(socket.request, function(err, authorized) {
if (err) return next(new Error(err));
if (!authorized) return next(new Error('Not authorized'));
next();
});
});
} else if ('origins' == key && val) {
this.origins(val);
} else if ('resource' == key) {
this.path(val);
} else if (oldSettings[key] && this.eio[oldSettings[key]]) {
this.eio[oldSettings[key]] = val;
} else {
console.error('Option %s is not valid. Please refer to the README.', key);
}
return this;
};
@@ -99,11 +160,28 @@ Server.prototype.adapter = function(v){
if (!arguments.length) return this._adapter;
this._adapter = v;
for (var i in this.nsps) {
this.nsps[i].initAdapter();
if (this.nsps.hasOwnProperty(i)) {
this.nsps[i].initAdapter();
}
}
return this;
};
/**
* Sets the allowed origins for requests.
*
* @param {String} origins
* @return {Server|Adapter} self when setting or value when getting
* @api public
*/
Server.prototype.origins = function(v){
if (!arguments.length) return this._origins;
this._origins = v;
return this;
};
/**
* Attaches socket.io to a server or port.
*
@@ -134,21 +212,27 @@ Server.prototype.attach = function(srv, opts){
res.end();
});
srv.listen(port);
}
// set engine.io path to `/socket.io`
opts = opts || {};
opts.path = opts.path || '/socket.io';
opts.path = opts.path || this.path();
// set origins verification
opts.allowRequest = this.checkRequest.bind(this);
// initialize engine
debug('creating engine.io instance with opts %j', opts);
var eio = engine.attach(srv, opts);
this.eio = engine.attach(srv, opts);
// attach static file serving
if (this._serveClient) this.attachServe(srv);
// Export http server
this.httpServer = srv;
// bind to engine events
this.bind(eio);
this.bind(this.eio);
return this;
};
@@ -186,8 +270,9 @@ Server.prototype.attachServe = function(srv){
*/
Server.prototype.serve = function(req, res){
if (req.headers.etag) {
if (clientVersion == req.headers.etag) {
var etag = req.headers['if-none-match'];
if (etag) {
if (clientVersion == etag) {
debug('serve client 304');
res.writeHead(304);
res.end();
@@ -240,6 +325,8 @@ Server.prototype.onconnection = function(conn){
*/
Server.prototype.of = function(name, fn){
if (String(name)[0] !== '/') name = '/' + name;
if (!this.nsps[name]) {
debug('initializing namespace %s', name);
var nsp = new Namespace(this, name);
@@ -249,6 +336,24 @@ Server.prototype.of = function(name, fn){
return this.nsps[name];
};
/**
* Closes server connection
*
* @api public
*/
Server.prototype.close = function(){
this.nsps['/'].sockets.forEach(function(socket){
socket.onclose();
});
this.engine.close();
if(this.httpServer){
this.httpServer.close();
}
};
/**
* Expose main namespace (/).
*/

View File

@@ -5,6 +5,7 @@
var Emitter = require('events').EventEmitter;
var parser = require('socket.io-parser');
var url = require('url');
var debug = require('debug')('socket.io:socket');
var hasBin = require('has-binary-data');
@@ -24,7 +25,8 @@ exports.events = [
'error',
'connect',
'disconnect',
'newListener'
'newListener',
'removeListener'
];
/**
@@ -65,6 +67,7 @@ function Socket(nsp, client){
this.acks = {};
this.connected = true;
this.disconnected = false;
this.handshake = this.buildHandshake();
}
/**
@@ -95,6 +98,25 @@ Socket.prototype.__defineGetter__('request', function(){
return this.conn.request;
});
/**
* Builds the `handshake` BC object
*
* @api private
*/
Socket.prototype.buildHandshake = function(){
return {
headers: this.request.headers,
time: (new Date) + '',
address: this.conn.remoteAddress,
xdomain: !!this.request.headers.origin,
secure: !!this.request.connection.encrypted,
issued: +(new Date),
url: this.request.url,
query: url.parse(this.request.url, true).query || {}
};
};
/**
* Emits to this client.
*
@@ -220,7 +242,7 @@ Socket.prototype.leave = function(room, fn){
this.adapter.del(this.id, room, function(err){
if (err) return fn && fn(err);
debug('left room %s', room);
self.rooms.splice(self.rooms.indexOf(room, 1));
self.rooms.splice(self.rooms.indexOf(room), 1);
fn && fn(null);
});
return this;
@@ -234,6 +256,7 @@ Socket.prototype.leave = function(room, fn){
Socket.prototype.leaveAll = function(){
this.adapter.delAll(this.id);
this.rooms = [];
};
/**
@@ -272,6 +295,10 @@ Socket.prototype.onpacket = function(packet){
this.onack(packet);
break;
case parser.BINARY_ACK:
this.onack(packet);
break;
case parser.DISCONNECT:
this.ondisconnect();
break;
@@ -315,9 +342,11 @@ Socket.prototype.ack = function(id){
if (sent) return;
var args = Array.prototype.slice.call(arguments);
debug('sending ack %j', args);
var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;
self.packet({
id: id,
type: parser.ACK,
type: type,
data: args
});
};

View File

@@ -1,6 +1,6 @@
{
"name": "socket.io",
"version": "1.0.0-pre",
"version": "1.2.0",
"description": "node.js realtime framework server",
"keywords": [
"realtime",
@@ -11,21 +11,26 @@
"socket",
"io"
],
"repository": {
"type": "git",
"url": "git://github.com/Automattic/socket.io"
},
"scripts": {
"test": "make test"
},
"dependencies": {
"engine.io": "1.0.4",
"socket.io-parser": "2.1.1",
"socket.io-client": "1.0.0-pre",
"socket.io-adapter": "0.2.0",
"has-binary-data": "0.1.0",
"engine.io": "1.4.2",
"socket.io-parser": "2.2.2",
"socket.io-client": "1.2.0",
"socket.io-adapter": "0.3.1",
"has-binary-data": "0.1.3",
"debug": "0.7.4"
},
"devDependencies": {
"mocha": "1.16.2",
"expect.js": "0.2.1",
"expect.js": "0.3.1",
"supertest": "0.8.2",
"superagent": "0.17.0",
"istanbul": "0.2.3"
},
"contributors": [

BIN
test/fixtures/big.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

174066
test/fixtures/big.json vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -20,6 +20,132 @@ function client(srv, nsp, opts){
}
describe('socket.io', function(){
it('should be the same version as client', function(){
var version = require('../package').version;
expect(version).to.be(require('socket.io-client/package').version);
});
describe('set', function() {
it('should be able to set ping timeout to engine.io', function() {
var srv = io(http());
srv.set('heartbeat timeout', 10);
expect(srv.eio.pingTimeout).to.be(10);
});
it('should be able to set ping interval to engine.io', function() {
var srv = io(http());
srv.set('heartbeat interval', 10);
expect(srv.eio.pingInterval).to.be(10);
});
it('should be able to set transports to engine.io', function() {
var srv = io(http());
srv.set('transports', ['polling']);
expect(srv.eio.transports).to.eql(['polling']);
});
it('should be able to set maxHttpBufferSize to engine.io', function() {
var srv = io(http());
srv.set('destroy buffer size', 10);
expect(srv.eio.maxHttpBufferSize).to.eql(10);
});
it('should be able to set path with setting resource', function(done) {
var eio = io();
var srv = http();
eio.set('resource', '/random');
eio.attach(srv);
// Check that the server is accessible through the specified path
request(srv)
.get('/random/socket.io.js')
.buffer(true)
.end(function(err, res){
if (err) return done(err);
done();
});
});
it('should be able to set origins to engine.io', function() {
var srv = io(http());
srv.set('origins', 'http://hostname.com:*');
expect(srv.origins()).to.be('http://hostname.com:*');
});
it('should be able to set authorization and send error packet', function(done) {
var httpSrv = http();
var srv = io(httpSrv);
srv.set('authorization', function(o, f) { f(null, false); });
var socket = client(httpSrv);
socket.on('connect', function(){
expect().fail();
});
socket.on('error', function(err) {
expect(err).to.be('Not authorized');
done();
});
});
it('should be able to set authorization and succeed', function(done) {
var httpSrv = http();
var srv = io(httpSrv);
srv.set('authorization', function(o, f) { f(null, true); });
srv.on('connection', function(s) {
s.on('yoyo', function(data) {
expect(data).to.be('data');
done();
});
});
var socket = client(httpSrv);
socket.on('connect', function(){
socket.emit('yoyo', 'data');
});
socket.on('error', function(err) {
expect().fail();
});
});
it('should set the handshake BC object', function(done){
var httpSrv = http();
var srv = io(httpSrv);
srv.on('connection', function(s) {
expect(s.handshake).to.not.be(undefined);
// Headers set and has some valid properties
expect(s.handshake.headers).to.be.an('object');
expect(s.handshake.headers['user-agent']).to.be('node-XMLHttpRequest');
// Time set and is valid looking string
expect(s.handshake.time).to.be.a('string');
expect(s.handshake.time.split(' ').length > 0); // Is "multipart" string representation
// Address, xdomain, secure, issued and url set
expect(s.handshake.address).to.be('127.0.0.1');
expect(s.handshake.xdomain).to.be.a('boolean');
expect(s.handshake.secure).to.be.a('boolean');
expect(s.handshake.issued).to.be.a('number');
expect(s.handshake.url).to.be.a('string');
// Query set and has some right properties
expect(s.handshake.query).to.be.an('object');
expect(s.handshake.query.EIO).to.not.be(undefined);
expect(s.handshake.query.transport).to.not.be(undefined);
expect(s.handshake.query.t).to.not.be(undefined);
done();
});
var socket = client(httpSrv);
});
});
describe('server attachment', function(){
describe('http.Server', function(){
var clientVersion = require('socket.io-client/package').version;
@@ -46,7 +172,7 @@ describe('socket.io', function(){
io(srv);
request(srv)
.get('/socket.io/socket.io.js')
.set('ETag', clientVersion)
.set('If-None-Match', clientVersion)
.end(function(err, res){
if (err) return done(err);
expect(res.statusCode).to.be(304);
@@ -87,6 +213,13 @@ describe('socket.io', function(){
.expect(200, done);
});
it('should be bound as a string', function(done) {
var sockets = io('54020');
request('http://localhost:54020')
.get('/socket.io/socket.io.js')
.expect(200, done);
});
it('with listen', function(done){
var sockets = io().listen(54011);
request('http://localhost:54011')
@@ -103,144 +236,375 @@ describe('socket.io', function(){
});
});
describe('handshake', function(){
var request = require('superagent');
it('should disallow request when origin defined and none specified', function(done) {
var sockets = io({ origins: 'http://foo.example:*' }).listen('54013');
request.get('http://localhost:54013/socket.io/default/')
.query({ transport: 'polling' })
.end(function (err, res) {
expect(res.status).to.be(400);
done();
});
});
it('should disallow request when origin defined and a different one specified', function(done) {
var sockets = io({ origins: 'http://foo.example:*' }).listen('54014');
request.get('http://localhost:54014/socket.io/default/')
.query({ transport: 'polling' })
.set('origin', 'http://herp.derp')
.end(function (err, res) {
expect(res.status).to.be(400);
done();
});
});
it('should allow request when origin defined an the same is specified', function(done) {
var sockets = io({ origins: 'http://foo.example:*' }).listen('54015');
request.get('http://localhost:54015/socket.io/default/')
.set('origin', 'http://foo.example')
.query({ transport: 'polling' })
.end(function (err, res) {
expect(res.status).to.be(200);
done();
});
});
it('should allow request when origin defined as function and same is supplied', function(done) {
var sockets = io({ origins: function(origin,callback){
if(origin == 'http://foo.example')
return callback(null, true);
return callback(null, false);
} }).listen('54016');
request.get('http://localhost:54016/socket.io/default/')
.set('origin', 'http://foo.example')
.query({ transport: 'polling' })
.end(function (err, res) {
expect(res.status).to.be(200);
done();
});
});
it('should allow request when origin defined as function and different is supplied', function(done) {
var sockets = io({ origins: function(origin,callback){
if(origin == 'http://foo.example')
return callback(null, true);
return callback(null, false);
} }).listen('54017');
request.get('http://localhost:54017/socket.io/default/')
.set('origin', 'http://herp.derp')
.query({ transport: 'polling' })
.end(function (err, res) {
expect(res.status).to.be(400);
done();
});
});
});
describe('close', function(){
it('should be able to close sio sending a srv', function(){
var PORT = 54018;
var srv = http().listen(PORT);
var sio = io(srv);
var net = require('net');
var server = net.createServer();
var clientSocket = client(srv, { reconnection: false });
clientSocket.on('disconnect', function init() {
expect(sio.nsps['/'].sockets.length).to.equal(0);
server.listen(PORT);
});
clientSocket.on('connect', function init() {
expect(sio.nsps['/'].sockets.length).to.equal(1);
sio.close();
});
server.once('listening', function() {
// PORT should be free
server.close(function(error){
expect(error).to.be(undefined);
});
});
});
it('should be able to close sio sending a port', function(){
var PORT = 54019;
var sio = io(PORT);
var net = require('net');
var server = net.createServer();
var clientSocket = ioc('ws://0.0.0.0:' + PORT);
clientSocket.on('disconnect', function init() {
expect(sio.nsps['/'].sockets.length).to.equal(0);
server.listen(PORT);
});
clientSocket.on('connect', function init() {
expect(sio.nsps['/'].sockets.length).to.equal(1);
sio.close();
});
server.once('listening', function() {
// PORT should be free
server.close(function(error){
expect(error).to.be(undefined);
});
});
});
});
describe('namespaces', function(){
var Socket = require('../lib/socket');
var Namespace = require('../lib/namespace');
describe('default', function(){
it('should be accessible through .sockets', function(){
var sio = io();
expect(sio.sockets).to.be.a(Namespace);
});
it('should be accessible through .sockets', function(){
var sio = io();
expect(sio.sockets).to.be.a(Namespace);
});
it('should be aliased', function(){
var sio = io();
expect(sio.use).to.be.a('function');
expect(sio.to).to.be.a('function');
expect(sio['in']).to.be.a('function');
expect(sio.emit).to.be.a('function');
expect(sio.send).to.be.a('function');
expect(sio.write).to.be.a('function');
});
it('should be aliased', function(){
var sio = io();
expect(sio.use).to.be.a('function');
expect(sio.to).to.be.a('function');
expect(sio['in']).to.be.a('function');
expect(sio.emit).to.be.a('function');
expect(sio.send).to.be.a('function');
expect(sio.write).to.be.a('function');
});
it('should automatically connect', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
socket.on('connect', function(){
done();
});
it('should automatically connect', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
socket.on('connect', function(){
done();
});
});
});
it('should fire a `connection` event', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
sio.on('connection', function(socket){
expect(socket).to.be.a(Socket);
done();
});
it('should fire a `connection` event', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
sio.on('connection', function(socket){
expect(socket).to.be.a(Socket);
done();
});
});
});
it('should fire a `connect` event', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
sio.on('connect', function(socket){
expect(socket).to.be.a(Socket);
done();
});
it('should fire a `connect` event', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
sio.on('connect', function(socket){
expect(socket).to.be.a(Socket);
done();
});
});
});
it('should work with many sockets', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var chat = client(srv, '/chat');
var news = client(srv, '/news');
var total = 2;
chat.on('connect', function(){
--total || done();
});
news.on('connect', function(){
--total || done();
});
it('should work with many sockets', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
sio.of('/chat');
sio.of('/news');
var chat = client(srv, '/chat');
var news = client(srv, '/news');
var total = 2;
chat.on('connect', function(){
--total || done();
});
news.on('connect', function(){
--total || done();
});
});
});
it('should work with `of` and many sockets', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var chat = client(srv, '/chat');
var news = client(srv, '/news');
var total = 2;
sio.of('/news').on('connection', function(socket){
expect(socket).to.be.a(Socket);
--total || done();
});
sio.of('/news').on('connection', function(socket){
expect(socket).to.be.a(Socket);
--total || done();
});
it('should be able to equivalently start with "" or "/" on server', function(done){
var srv = http();
var sio = io(srv);
var total = 2;
sio.of('').on('connection', function(){
--total || done();
});
sio.of('abc').on('connection', function(){
--total || done();
});
var c1 = client(srv, '/');
var c2 = client(srv, '/abc');
});
it('should be equivalent for "" and "/" on client', function(done){
var srv = http();
var sio = io(srv);
sio.of('/').on('connection', function(){
done();
});
var c1 = client(srv, '');
});
it('should work with `of` and many sockets', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var chat = client(srv, '/chat');
var news = client(srv, '/news');
var total = 2;
sio.of('/news').on('connection', function(socket){
expect(socket).to.be.a(Socket);
--total || done();
});
sio.of('/news').on('connection', function(socket){
expect(socket).to.be.a(Socket);
--total || done();
});
});
});
it('should work with `of` second param', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var chat = client(srv, '/chat');
var news = client(srv, '/news');
var total = 2;
sio.of('/news', function(socket){
expect(socket).to.be.a(Socket);
--total || done();
});
sio.of('/news', function(socket){
expect(socket).to.be.a(Socket);
--total || done();
});
it('should work with `of` second param', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var chat = client(srv, '/chat');
var news = client(srv, '/news');
var total = 2;
sio.of('/news', function(socket){
expect(socket).to.be.a(Socket);
--total || done();
});
sio.of('/news', function(socket){
expect(socket).to.be.a(Socket);
--total || done();
});
});
});
it('should disconnect upon transport disconnection', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var chat = client(srv, '/chat');
var news = client(srv, '/news');
var total = 2;
var totald = 2;
var s;
sio.of('/news', function(socket){
socket.on('disconnect', function(reason){
--totald || done();
});
--total || close();
it('should disconnect upon transport disconnection', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var chat = client(srv, '/chat');
var news = client(srv, '/news');
var total = 2;
var totald = 2;
var s;
sio.of('/news', function(socket){
socket.on('disconnect', function(reason){
--totald || done();
});
sio.of('/chat', function(socket){
s = socket;
socket.on('disconnect', function(reason){
--totald || done();
});
--total || close();
--total || close();
});
sio.of('/chat', function(socket){
s = socket;
socket.on('disconnect', function(reason){
--totald || done();
});
function close(){
s.disconnect(true);
}
--total || close();
});
function close(){
s.disconnect(true);
}
});
});
it('should disconnect both default and custom namespace upon disconnect', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var lolcats = client(srv, '/lolcats');
var total = 2;
var totald = 2;
var s;
sio.of('/', function(socket){
socket.on('disconnect', function(reason){
--totald || done();
});
--total || close();
});
sio.of('/lolcats', function(socket){
s = socket;
socket.on('disconnect', function(reason){
--totald || done();
});
--total || close();
});
function close(){
s.disconnect(true);
}
});
});
it('should not crash while disconnecting socket', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv,'/ns');
sio.on('connection', function(socket){
socket.disconnect();
done();
});
});
});
it('should return error connecting to non-existent namespace', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv,'/doesnotexist');
socket.on('error', function(err) {
expect(err).to.be('Invalid namespace');
done();
});
});
});
});
describe('socket', function(){
it('should not fire events more than once after manually reconnecting', function(done) {
var srv = http();
var sio = io(srv);
srv.listen(function(){
var clientSocket = client(srv, { reconnection: false });
clientSocket.on('connect', function init() {
clientSocket.removeListener('connect', init);
clientSocket.io.engine.close();
clientSocket.connect();
clientSocket.on('connect', function() {
done();
});
});
});
});
it('should not fire reconnect_failed event more than once when server closed', function(done) {
var srv = http();
var sio = io(srv);
srv.listen(function(){
var clientSocket = client(srv, { reconnectionAttempts: 3, reconnectionDelay: 10 });
clientSocket.on('connect', function() {
srv.close();
});
clientSocket.on('reconnect_failed', function() {
done();
});
});
});
it('should receive events', function(done){
var srv = http();
var sio = io(srv);
@@ -288,6 +652,28 @@ describe('socket.io', function(){
});
});
it('should emit events with utf8 multibyte character', function(done) {
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
var i = 0;
socket.on('hoot', function(a){
expect(a).to.be('utf8 — string');
i++;
if (3 == i) {
done();
}
});
sio.on('connection', function(s){
s.emit('hoot', 'utf8 — string');
s.emit('hoot', 'utf8 — string');
s.emit('hoot', 'utf8 — string');
});
});
});
it('should emit events with binary data', function(done){
var srv = http();
var sio = io(srv);
@@ -412,6 +798,30 @@ describe('socket.io', function(){
});
});
it('should receive all events emitted from namespaced client immediately and in order', function(done) {
var srv = http();
var sio = io(srv);
var total = 0;
srv.listen(function(){
sio.of('/chat', function(s){
s.on('hi', function(letter){
total++;
if (total == 2 && letter == 'b') {
done();
} else if (total == 1 && letter != 'a') {
throw new Error('events out of order');
}
});
});
var chat = client(srv, '/chat');
chat.emit('hi', 'a');
setTimeout(function() {
chat.emit('hi', 'b');
}, 50);
});
});
it('should emit events with callbacks', function(done){
var srv = http();
var sio = io(srv);
@@ -464,6 +874,76 @@ describe('socket.io', function(){
});
});
it('should receive events with binary args and callbacks', function(done) {
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
sio.on('connection', function(s){
s.on('woot', function(buf, fn){
expect(Buffer.isBuffer(buf)).to.be(true);
fn(1, 2);
});
socket.emit('woot', new Buffer(3), function(a, b){
expect(a).to.be(1);
expect(b).to.be(2);
done();
});
});
});
});
it('should emit events with binary args and callback', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
sio.on('connection', function(s){
socket.on('hi', function(a, fn){
expect(Buffer.isBuffer(a)).to.be(true);
fn();
});
s.emit('hi', new Buffer(4), function(){
done();
});
});
});
});
it('should emit events and receive binary data in a callback', function(done) {
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
sio.on('connection', function(s){
socket.on('hi', function(fn){
fn(new Buffer(1));
});
s.emit('hi', function(a){
expect(Buffer.isBuffer(a)).to.be(true);
done();
});
});
});
});
it('should receive events and pass binary data in a callback', function(done) {
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
sio.on('connection', function(s){
s.on('woot', function(fn){
fn(new Buffer(2));
});
socket.emit('woot', function(a){
expect(Buffer.isBuffer(a)).to.be(true);
done();
});
});
});
});
it('should have access to the client', function(done){
var srv = http();
var sio = io(srv);
@@ -501,6 +981,76 @@ describe('socket.io', function(){
});
});
});
it('should see query parameters in the request', function(done) {
var srv = http();
var sio = io(srv);
srv.listen(function() {
var addr = srv.listen().address();
var url = 'ws://' + addr.address + ':' + addr.port + '?key1=1&key2=2';
var socket = ioc(url);
sio.on('connection', function(s) {
var parsed = require('url').parse(s.request.url);
var query = require('querystring').parse(parsed.query);
expect(query.key1).to.be('1');
expect(query.key2).to.be('2');
done();
});
});
});
it('should handle very large json', function(done){
this.timeout();
var srv = http();
var sio = io(srv);
var received = 0;
srv.listen(function(){
var socket = client(srv);
socket.on('big', function(a){
expect(Buffer.isBuffer(a.json)).to.be(false);
if (++received == 3)
done();
else
socket.emit('big', a);
});
sio.on('connection', function(s){
fs.readFile(join(__dirname, 'fixtures', 'big.json'), function(err, data){
if (err) return done(err);
data = JSON.parse(data);
s.emit('big', {hello: 'friend', json: data});
});
s.on('big', function(a){
s.emit('big', a);
});
});
});
});
it('should handle very large binary data', function(done){
var srv = http();
var sio = io(srv);
var received = 0;
srv.listen(function(){
var socket = client(srv);
socket.on('big', function(a){
expect(Buffer.isBuffer(a.image)).to.be(true);
if (++received == 3)
done();
else
socket.emit('big', a);
});
sio.on('connection', function(s){
fs.readFile(join(__dirname, 'fixtures', 'big.jpg'), function(err, data){
if (err) return done(err);
s.emit('big', {hello: 'friend', image: data});
});
s.on('big', function(a){
expect(Buffer.isBuffer(a.image)).to.be(true);
s.emit('big', a);
});
});
});
});
});
describe('messaging many', function(){
@@ -768,15 +1318,38 @@ describe('socket.io', function(){
expect(s.rooms).to.eql([s.id, 'a']);
s.join('b', function(){
expect(s.rooms).to.eql([s.id, 'a', 'b']);
s.leave('b', function(){
expect(s.rooms).to.eql([s.id, 'a']);
done();
s.join( 'c', function(){
expect(s.rooms).to.eql([s.id, 'a', 'b', 'c']);
s.leave('b', function(){
expect(s.rooms).to.eql([s.id, 'a', 'c']);
s.leaveAll();
expect(s.rooms).to.eql([]);
done();
});
});
});
});
});
});
});
it('deletes empty rooms', function(done) {
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
sio.on('connection', function(s){
s.join('a', function(){
expect(s.nsp.adapter.rooms).to.have.key('a');
s.leave('a', function(){
expect(s.nsp.adapter.rooms).to.not.have.key('a');
done();
});
});
});
});
});
});
describe('middleware', function(done){