Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'v0.6'

Conflicts:
	ChangeLog
	doc/template.html
	lib/cluster.js
	lib/http.js
	lib/tls.js
	src/node.h
	src/node_version.h
	test/simple/test-cluster-kill-workers.js
  • Loading branch information...
commit 667aae596cded9336f50574386683ec39ada43f2 2 parents 2433eeb + 6c0c00a
@indutny indutny authored
Showing with 1,874 additions and 385 deletions.
  1. +5 −0 AUTHORS
  2. +26 −1 ChangeLog
  3. +542 −5 doc/api/addons.markdown
  4. +1 −1  doc/api/appendix_1.markdown
  5. +5 −1 doc/community/index.html
  6. +7 −7 doc/index.html
  7. +1 −1  doc/logos/index.html
  8. +7 −3 lib/child_process.js
  9. +26 −8 lib/dgram.js
  10. +19 −3 lib/http.js
  11. +2 −2 lib/path.js
  12. +10 −9 lib/tls.js
  13. +7 −0 lib/tty.js
  14. +13 −14 lib/util.js
  15. +12 −8 lib/zlib.js
  16. +1 −0  src/node_crypto.cc
  17. +73 −0 src/udp_wrap.cc
  18. +15 −0 src/v8_typed_array.cc
  19. +1 −1  test/common.js
  20. +2 −2 test/internet/test-dns.js
  21. +1 −1  test/message/throw_custom_error.js
  22. +1 −1  test/message/throw_non_error.js
  23. +7 −7 test/pummel/test-net-timeout2.js
  24. +1 −1  test/simple/test-assert.js
  25. +10 −5 test/simple/test-child-process-double-pipe.js
  26. +3 −3 test/simple/test-child-process-fork2.js
  27. +59 −0 test/simple/test-cluster-uncaught-exception.js
  28. +4 −5 test/simple/test-crypto-ecb.js
  29. +160 −0 test/simple/test-dgram-broadcast-multi-process.js
  30. +160 −0 test/simple/test-dgram-multicast-multi-process.js
  31. +41 −0 test/simple/test-dgram-multicast-setTTL.js
  32. +2 −2 test/simple/test-dgram-send-error.js
  33. +2 −2 test/simple/test-eval.js
  34. +8 −8 test/simple/test-executable-path.js
  35. +4 −2 test/simple/test-fs-long-path.js
  36. +1 −1  test/simple/test-fs-mkdir.js
  37. +4 −6 test/simple/test-fs-symlink.js
  38. +5 −5 test/simple/test-fs-utimes.js
  39. +4 −2 test/simple/test-http-1.0.js
  40. +1 −1  test/simple/test-http-abort-before-end.js
  41. +54 −0 test/simple/test-http-parser-free.js
  42. +3 −3 test/simple/test-http-res-write-end-dont-take-array.js
  43. +5 −4 test/simple/test-http-response-no-headers.js
  44. +71 −0 test/simple/test-http-should-keep-alive.js
  45. +10 −5 test/simple/test-init.js
  46. +7 −6 test/simple/test-module-load-list.js
  47. +1 −1  test/simple/test-net-connect-buffer.js
  48. +12 −14 test/simple/test-net-pipe-connect-errors.js
  49. +48 −46 test/simple/test-net-server-max-connections.js
  50. +4 −4 test/simple/test-path-makelong.js
  51. +35 −3 test/simple/test-path.js
  52. +41 −40 test/simple/test-punycode.js
  53. +1 −1  test/simple/test-readdir.js
  54. +6 −4 test/simple/test-regress-GH-1899.js
  55. +10 −5 test/simple/test-regress-GH-877.js
  56. +10 −13 test/simple/test-repl-.save.load.js
  57. +55 −46 test/simple/test-repl-tab-complete.js
  58. +4 −2 test/simple/test-script-context.js
  59. +2 −2 test/simple/test-setproctitle.js
  60. +1 −1  test/simple/test-stdin-child-proc.js
  61. +6 −6 test/simple/test-stdin-pause-resume.js
  62. +45 −0 test/simple/test-tls-client-abort2.js
  63. +1 −1  test/simple/test-tls-passphrase.js
  64. +3 −3 test/simple/test-tls-session-cache.js
  65. +2 −1  test/simple/test-tls-set-ciphers.js
  66. +1 −1  test/simple/test-tty-stdout-end.js
  67. +48 −0 test/simple/test-typed-arrays-typenames.js
  68. +24 −3 test/simple/test-util-inspect.js
  69. +37 −37 test/simple/test-util.js
  70. +1 −1  test/simple/test-zlib-from-gzip.js
  71. +28 −7 test/simple/test-zlib-from-string.js
  72. +38 −0 test/simple/test-zlib-invalid-input.js
  73. +7 −7 test/simple/test-zlib-random-byte-pipes.js
View
5 AUTHORS
@@ -253,3 +253,8 @@ Dave Irvine <davman99@gmail.com>
Ju-yeong Park <interruptz@gmail.com>
Phil Sung <psung@dnanexus.com>
Damon Oehlman <damon.oehlman@sidelab.com>
+Ryunosuke SATO <tricknotes.rs@gmail.com>
+Michael Bernstein <michaelrbernstein@gmail.com>
+Guillermo Rauch <rauchg@gmail.com>
+Dan Williams <dan@igniter.com>
+Brandon Benvie <brandon@bbenvie.com>
View
27 ChangeLog
@@ -13,7 +13,32 @@
* Bug fixes
-2012.01.06, Version 0.6.7 (stable)
+2012.01.19, Version 0.6.8 (stable)
+
+* Update V8 to 3.6.6.19
+
+* Numeric key hash collision fix for V8 (Erik Corry, Fedor Indutny)
+
+* Add missing TTY key translations for F1-F5 on Windows (Brandon Benvie)
+
+* path.extname bugfix with . and .. paths (Bert Belder)
+
+* cluster: don't always kill the master on uncaughtException (Ben Noordhuis)
+
+* Update npm to 1.1.0-2 (isaacs)
+
+* typed arrays: set class name (Ben Noordhuis)
+
+* zlib binding cleanup (isaacs, Bert Belder)
+
+* dgram: use slab memory allocator (Michael Bernstein)
+
+* fix segfault #2473
+
+* #2521 60% improvement in fs.stat on Windows (Igor Zinkovsky)
+
+
+2012.01.06, Version 0.6.7 (stable), d5a189acef14a851287ee555f7a39431fe276e1c
* V8 hash collision fix (Breaks MIPS) (Bert Belder, Erik Corry)
View
547 doc/api/addons.markdown
@@ -6,7 +6,8 @@ knowledge of several libraries:
- V8 JavaScript, a C++ library. Used for interfacing with JavaScript:
creating objects, calling functions, etc. Documented mostly in the
- `v8.h` header file (`deps/v8/include/v8.h` in the Node source tree).
+ `v8.h` header file (`deps/v8/include/v8.h` in the Node source tree),
+ which is also available [online](http://izs.me/v8-docs/main.html).
- [libuv](https://github.com/joyent/libuv), C event loop library. Anytime one
needs to wait for a file descriptor to become readable, wait for a timer, or
@@ -22,12 +23,15 @@ Node statically compiles all its dependencies into the executable. When
compiling your module, you don't need to worry about linking to any of these
libraries.
+
+### Hello world
+
To get started let's make a small Addon which is the C++ equivalent of
the following Javascript code:
exports.hello = function() { return 'world'; };
-To get started we create a file `hello.cc`:
+First we create a file `hello.cc`:
#include <node.h>
#include <v8.h>
@@ -40,7 +44,8 @@ To get started we create a file `hello.cc`:
}
void init(Handle<Object> target) {
- NODE_SET_METHOD(target, "hello", Method);
+ target->Set(String::NewSymbol("hello"),
+ FunctionTemplate::New(Method)->GetFunction());
}
NODE_MODULE(hello, init)
@@ -87,5 +92,537 @@ the recently built module:
console.log(addon.hello()); // 'world'
-For the moment, that is all the documentation on addons. Please see
-<https://github.com/pietern/hiredis-node> for a real example.
+Please see patterns below for further information or
+<https://github.com/pietern/hiredis-node> for an example in production.
+
+
+## Addon patterns
+
+Below are some addon patterns to help you get started. Consult the online
+[v8 reference](http://izs.me/v8-docs/main.html) for help with the various v8
+calls, and v8's [Embedder's Guide](http://code.google.com/apis/v8/embed.html)
+for an explanation of several concepts used such as handles, scopes,
+function templates, etc.
+
+To compile these examples, create the `wscript` file below and run
+`node-waf configure build`:
+
+ srcdir = '.'
+ blddir = 'build'
+ VERSION = '0.0.1'
+
+ def set_options(opt):
+ opt.tool_options('compiler_cxx')
+
+ def configure(conf):
+ conf.check_tool('compiler_cxx')
+ conf.check_tool('node_addon')
+
+ def build(bld):
+ obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
+ obj.target = 'addon'
+ obj.source = ['addon.cc']
+
+In cases where there is more than one `.cc` file, simply add the file name to the
+`obj.source` array, e.g.:
+
+ obj.source = ['addon.cc', 'myexample.cc']
+
+
+#### Function arguments
+
+The following pattern illustrates how to read arguments from JavaScript
+function calls and return a result. This is the main and only needed source
+`addon.cc`:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+
+ using namespace v8;
+
+ Handle<Value> Add(const Arguments& args) {
+ HandleScope scope;
+
+ if (args.Length() < 2) {
+ ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));
+ return scope.Close(Undefined());
+ }
+
+ if (!args[0]->IsNumber() || !args[1]->IsNumber()) {
+ ThrowException(Exception::TypeError(String::New("Wrong arguments")));
+ return scope.Close(Undefined());
+ }
+
+ Local<Number> num = Number::New(args[0]->NumberValue() +
+ args[1]->NumberValue());
+ return scope.Close(num);
+ }
+
+ void Init(Handle<Object> target) {
+ target->Set(String::NewSymbol("add"),
+ FunctionTemplate::New(Add)->GetFunction());
+ }
+
+ NODE_MODULE(addon, Init)
+
+You can test it with the following JavaScript snippet:
+
+ var addon = require('./build/Release/addon');
+
+ console.log( 'This should be eight:', addon.add(3,5) );
+
+
+#### Callbacks
+
+You can pass JavaScript functions to a C++ function and execute them from
+there. Here's `addon.cc`:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+
+ using namespace v8;
+
+ Handle<Value> RunCallback(const Arguments& args) {
+ HandleScope scope;
+
+ Local<Function> cb = Local<Function>::Cast(args[0]);
+ const unsigned argc = 1;
+ Local<Value> argv[argc] = { Local<Value>::New(String::New("hello world")) };
+ cb->Call(Context::GetCurrent()->Global(), argc, argv);
+
+ return scope.Close(Undefined());
+ }
+
+ void Init(Handle<Object> target) {
+ target->Set(String::NewSymbol("runCallback"),
+ FunctionTemplate::New(RunCallback)->GetFunction());
+ }
+
+ NODE_MODULE(addon, Init)
+
+To test it run the following JavaScript snippet:
+
+ var addon = require('./build/Release/addon');
+
+ addon.runCallback(function(msg){
+ console.log(msg); // 'hello world'
+ });
+
+
+#### Object factory
+
+You can create and return new objects from within a C++ function with this
+`addon.cc` pattern, which returns an object with property `msg` that echoes
+the string passed to `createObject()`:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+
+ using namespace v8;
+
+ Handle<Value> CreateObject(const Arguments& args) {
+ HandleScope scope;
+
+ Local<Object> obj = Object::New();
+ obj->Set(String::NewSymbol("msg"), args[0]->ToString());
+
+ return scope.Close(obj);
+ }
+
+ void Init(Handle<Object> target) {
+ target->Set(String::NewSymbol("createObject"),
+ FunctionTemplate::New(CreateObject)->GetFunction());
+ }
+
+ NODE_MODULE(addon, Init)
+
+To test it in JavaScript:
+
+ var addon = require('./build/Release/addon');
+
+ var obj1 = addon.createObject('hello');
+ var obj2 = addon.createObject('world');
+ console.log(obj1.msg+' '+obj2.msg); // 'hello world'
+
+
+#### Function factory
+
+This pattern illustrates how to create and return a JavaScript function that
+wraps a C++ function:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+
+ using namespace v8;
+
+ Handle<Value> MyFunction(const Arguments& args) {
+ HandleScope scope;
+ return scope.Close(String::New("hello world"));
+ }
+
+ Handle<Value> CreateFunction(const Arguments& args) {
+ HandleScope scope;
+
+ Local<FunctionTemplate> tpl = FunctionTemplate::New(MyFunction);
+ Local<Function> fn = tpl->GetFunction();
+ fn->SetName(String::NewSymbol("theFunction")); // omit this to make it anonymous
+
+ return scope.Close(fn);
+ }
+
+ void Init(Handle<Object> target) {
+ target->Set(String::NewSymbol("createFunction"),
+ FunctionTemplate::New(CreateFunction)->GetFunction());
+ }
+
+ NODE_MODULE(addon, Init)
+
+
+To test:
+
+ var addon = require('./build/Release/addon');
+
+ var fn = addon.createFunction();
+ console.log(fn()); // 'hello world'
+
+
+#### Wrapping C++ objects
+
+Here we will create a wrapper for a C++ object/class `MyObject` that can be
+instantiated in JavaScript through the `new` operator. First prepare the main
+module `addon.cc`:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+ #include "myobject.h"
+
+ using namespace v8;
+
+ void InitAll(Handle<Object> target) {
+ MyObject::Init(target);
+ }
+
+ NODE_MODULE(addon, InitAll)
+
+Then in `myobject.h` make your wrapper inherit from `node::ObjectWrap`:
+
+ #ifndef MYOBJECT_H
+ #define MYOBJECT_H
+
+ #include <node.h>
+
+ class MyObject : public node::ObjectWrap {
+ public:
+ static void Init(v8::Handle<v8::Object> target);
+
+ private:
+ MyObject();
+ ~MyObject();
+
+ static v8::Handle<v8::Value> New(const v8::Arguments& args);
+ static v8::Handle<v8::Value> PlusOne(const v8::Arguments& args);
+ double counter_;
+ };
+
+ #endif
+
+And in `myobject.cc` implement the various methods that you want to expose.
+Here we expose the method `plusOne` by adding it to the constructor's
+prototype:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+ #include "myobject.h"
+
+ using namespace v8;
+
+ MyObject::MyObject() {};
+ MyObject::~MyObject() {};
+
+ void MyObject::Init(Handle<Object> target) {
+ // Prepare constructor template
+ Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
+ tpl->SetClassName(String::NewSymbol("MyObject"));
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
+ // Prototype
+ tpl->PrototypeTemplate()->Set(String::NewSymbol("plusOne"),
+ FunctionTemplate::New(PlusOne)->GetFunction());
+
+ Persistent<Function> constructor = Persistent<Function>::New(tpl->GetFunction());
+ target->Set(String::NewSymbol("MyObject"), constructor);
+ }
+
+ Handle<Value> MyObject::New(const Arguments& args) {
+ HandleScope scope;
+
+ MyObject* obj = new MyObject();
+ obj->counter_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
+ obj->Wrap(args.This());
+
+ return args.This();
+ }
+
+ Handle<Value> MyObject::PlusOne(const Arguments& args) {
+ HandleScope scope;
+
+ MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.This());
+ obj->counter_ += 1;
+
+ return scope.Close(Number::New(obj->counter_));
+ }
+
+Test it with:
+
+ var addon = require('./build/Release/addon');
+
+ var obj = new addon.MyObject(10);
+ console.log( obj.plusOne() ); // 11
+ console.log( obj.plusOne() ); // 12
+ console.log( obj.plusOne() ); // 13
+
+
+#### Factory of wrapped objects
+
+This is useful when you want to be able to create native objects without
+explicitly instantiating them with the `new` operator in JavaScript, e.g.
+
+ var obj = addon.createObject();
+ // instead of:
+ // var obj = new addon.Object();
+
+Let's register our `createObject` method in `addon.cc`:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+ #include "myobject.h"
+
+ using namespace v8;
+
+ Handle<Value> CreateObject(const Arguments& args) {
+ HandleScope scope;
+ return scope.Close(MyObject::NewInstance(args));
+ }
+
+ void InitAll(Handle<Object> target) {
+ MyObject::Init();
+
+ target->Set(String::NewSymbol("createObject"),
+ FunctionTemplate::New(CreateObject)->GetFunction());
+ }
+
+ NODE_MODULE(addon, InitAll)
+
+In `myobject.h` we now introduce the static method `NewInstance` that takes
+care of instantiating the object (i.e. it does the job of `new` in JavaScript):
+
+ #define BUILDING_NODE_EXTENSION
+ #ifndef MYOBJECT_H
+ #define MYOBJECT_H
+
+ #include <node.h>
+
+ class MyObject : public node::ObjectWrap {
+ public:
+ static void Init();
+ static v8::Handle<v8::Value> NewInstance(const v8::Arguments& args);
+
+ private:
+ MyObject();
+ ~MyObject();
+
+ static v8::Persistent<v8::Function> constructor;
+ static v8::Handle<v8::Value> New(const v8::Arguments& args);
+ static v8::Handle<v8::Value> PlusOne(const v8::Arguments& args);
+ double counter_;
+ };
+
+ #endif
+
+The implementation is similar to the above in `myobject.cc`:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+ #include "myobject.h"
+
+ using namespace v8;
+
+ MyObject::MyObject() {};
+ MyObject::~MyObject() {};
+
+ Persistent<Function> MyObject::constructor;
+
+ void MyObject::Init() {
+ // Prepare constructor template
+ Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
+ tpl->SetClassName(String::NewSymbol("MyObject"));
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
+ // Prototype
+ tpl->PrototypeTemplate()->Set(String::NewSymbol("plusOne"),
+ FunctionTemplate::New(PlusOne)->GetFunction());
+
+ constructor = Persistent<Function>::New(tpl->GetFunction());
+ }
+
+ Handle<Value> MyObject::New(const Arguments& args) {
+ HandleScope scope;
+
+ MyObject* obj = new MyObject();
+ obj->counter_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
+ obj->Wrap(args.This());
+
+ return args.This();
+ }
+
+ Handle<Value> MyObject::NewInstance(const Arguments& args) {
+ HandleScope scope;
+
+ const unsigned argc = 1;
+ Handle<Value> argv[argc] = { args[0] };
+ Local<Object> instance = constructor->NewInstance(argc, argv);
+
+ return scope.Close(instance);
+ }
+
+ Handle<Value> MyObject::PlusOne(const Arguments& args) {
+ HandleScope scope;
+
+ MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.This());
+ obj->counter_ += 1;
+
+ return scope.Close(Number::New(obj->counter_));
+ }
+
+Test it with:
+
+ var addon = require('./build/Release/addon');
+
+ var obj = addon.createObject(10);
+ console.log( obj.plusOne() ); // 11
+ console.log( obj.plusOne() ); // 12
+ console.log( obj.plusOne() ); // 13
+
+ var obj2 = addon.createObject(20);
+ console.log( obj2.plusOne() ); // 21
+ console.log( obj2.plusOne() ); // 22
+ console.log( obj2.plusOne() ); // 23
+
+
+#### Passing wrapped objects around
+
+In addition to wrapping and returning C++ objects, you can pass them around
+by unwrapping them with Node's `node::ObjectWrap::Unwrap` helper function.
+In the following `addon.cc` we introduce a function `add()` that can take on two
+`MyObject` objects:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+ #include "myobject.h"
+
+ using namespace v8;
+
+ Handle<Value> CreateObject(const Arguments& args) {
+ HandleScope scope;
+ return scope.Close(MyObject::NewInstance(args));
+ }
+
+ Handle<Value> Add(const Arguments& args) {
+ HandleScope scope;
+
+ MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>(
+ args[0]->ToObject());
+ MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>(
+ args[1]->ToObject());
+
+ double sum = obj1->Val() + obj2->Val();
+ return scope.Close(Number::New(sum));
+ }
+
+ void InitAll(Handle<Object> target) {
+ MyObject::Init();
+
+ target->Set(String::NewSymbol("createObject"),
+ FunctionTemplate::New(CreateObject)->GetFunction());
+
+ target->Set(String::NewSymbol("add"),
+ FunctionTemplate::New(Add)->GetFunction());
+ }
+
+ NODE_MODULE(addon, InitAll)
+
+To make things interesting we introduce a public method in `myobject.h` so we
+can probe private values after unwrapping the object:
+
+ #define BUILDING_NODE_EXTENSION
+ #ifndef MYOBJECT_H
+ #define MYOBJECT_H
+
+ #include <node.h>
+
+ class MyObject : public node::ObjectWrap {
+ public:
+ static void Init();
+ static v8::Handle<v8::Value> NewInstance(const v8::Arguments& args);
+ double Val() const { return val_; }
+
+ private:
+ MyObject();
+ ~MyObject();
+
+ static v8::Persistent<v8::Function> constructor;
+ static v8::Handle<v8::Value> New(const v8::Arguments& args);
+ double val_;
+ };
+
+ #endif
+
+The implementation of `myobject.cc` is similar as before:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+ #include "myobject.h"
+
+ using namespace v8;
+
+ MyObject::MyObject() {};
+ MyObject::~MyObject() {};
+
+ Persistent<Function> MyObject::constructor;
+
+ void MyObject::Init() {
+ // Prepare constructor template
+ Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
+ tpl->SetClassName(String::NewSymbol("MyObject"));
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
+
+ constructor = Persistent<Function>::New(tpl->GetFunction());
+ }
+
+ Handle<Value> MyObject::New(const Arguments& args) {
+ HandleScope scope;
+
+ MyObject* obj = new MyObject();
+ obj->val_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
+ obj->Wrap(args.This());
+
+ return args.This();
+ }
+
+ Handle<Value> MyObject::NewInstance(const Arguments& args) {
+ HandleScope scope;
+
+ const unsigned argc = 1;
+ Handle<Value> argv[argc] = { args[0] };
+ Local<Object> instance = constructor->NewInstance(argc, argv);
+
+ return scope.Close(instance);
+ }
+
+Test it with:
+
+ var addon = require('./build/Release/addon');
+
+ var obj1 = addon.createObject(10);
+ var obj2 = addon.createObject(20);
+ var result = addon.add(obj1, obj2);
+
+ console.log(result); // 30
View
2  doc/api/appendix_1.markdown
@@ -38,7 +38,7 @@ elsewhere.
- [ncurses](https://github.com/mscdex/node-ncurses)
- Testing/TDD/BDD: [vows](http://vowsjs.org/),
- [expresso](https://github.com/visionmedia/expresso),
+ [mocha](https://github.com/visionmedia/mocha),
[mjsunit.runner](https://github.com/tmpvar/mjsunit.runner)
Patches to this list are welcome.
View
6 doc/community/index.html
@@ -28,7 +28,11 @@
</div>
<div id="content" class="clearfix">
<div id="column1" class="interior">
- <p>Node's most valuable feature is the friendly and colorful community of developers. There are many places where this group congregates on the internet. This page attempts to highlight the best forums.</p>
+ <p>Node's most valuable feature is the friendly and <a
+ href="http://blip.tv/jsconf/nodeconf-2011-marak-squires-5729610">colorful
+ community</a> of developers. There are many places where
+ this group congregates on the internet. This page attempts
+ to highlight the best forums.</p>
<h2>Periodicals</h2>
View
14 doc/index.html
@@ -77,15 +77,15 @@
<a href="#" id="download-close">X</a>
<img id="download-logo" src="download-logo.png" alt="node.js">
<ul id="installers" class="clearfix">
- <li><a href="http://nodejs.org/dist/v0.6.7/node-v0.6.7.msi">Windows Installer</a><br>node-v0.6.7.msi</li>
- <li><a href="http://nodejs.org/dist/v0.6.7/node-v0.6.7.pkg">Macintosh Installer</a><br>node-v0.6.7.pkg</li>
- <li id="source"><a href="http://nodejs.org/dist/v0.6.7/node-v0.6.7.tar.gz">Source Code</a><br>node-v0.6.7.tar.gz</li>
+ <li><a href="http://nodejs.org/dist/v0.6.8/node-v0.6.8.msi">Windows Installer</a><br>node-v0.6.8.msi</li>
+ <li><a href="http://nodejs.org/dist/v0.6.8/node-v0.6.8.pkg">Macintosh Installer</a><br>node-v0.6.8.pkg</li>
+ <li id="source"><a href="http://nodejs.org/dist/v0.6.8/node-v0.6.8.tar.gz">Source Code</a><br>node-v0.6.8.tar.gz</li>
</ul>
<ul id="documentation">
- <li><a href="https://raw.github.com/joyent/node/v0.6.7/ChangeLog">Change Log</a></li>
- <li><a href="http://nodejs.org/docs/v0.6.7/api/index.html">Documentation</a></li>
- <li><a href="http://nodejs.org/dist/v0.6.7">Other release files</a></li>
- <li><a href="https://raw.github.com/joyent/node/v0.6.7/LICENSE">License</a></li>
+ <li><a href="https://raw.github.com/joyent/node/v0.6.8/ChangeLog">Change Log</a></li>
+ <li><a href="http://nodejs.org/docs/v0.6.8/api/index.html">Documentation</a></li>
+ <li><a href="http://nodejs.org/dist/v0.6.8">Other release files</a></li>
+ <li><a href="https://raw.github.com/joyent/node/v0.6.8/LICENSE">License</a></li>
<li><a href="https://github.com/joyent/node">Git Repository</a></li>
<li><a href="https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager">Installing
with a Package Manager</a>
View
2  doc/logos/index.html
@@ -60,7 +60,7 @@
</div>
</div>
<div id="footer">
- <p>Copyright <a href="http://joyent.com">Joyent, Inc</a>., Node.js is a <a href="trademark-policy.pdf">trademark of Joyent, Inc</a>., <a href="https://raw.github.com/joyent/node/v0.6.7/LICENSE">View License</a></p>
+ <p>Copyright <a href="http://joyent.com">Joyent, Inc</a>., Node.js is a <a href="trademark-policy.pdf">trademark of Joyent, Inc</a>., <a href="https://raw.github.com/joyent/node/v0.6.8/LICENSE">View License</a></p>
</div>
View
10 lib/child_process.js
@@ -146,7 +146,7 @@ function setupChannel(target, channel) {
var writeReq = channel.write(buffer, 0, buffer.length, sendHandle);
if (!writeReq) {
- throw new Error(errno + 'cannot write to IPC channel.');
+ throw errnoException(errno, 'write', 'cannot write to IPC channel.');
}
writeReq.oncomplete = nop;
@@ -496,11 +496,15 @@ ChildProcess.prototype.spawn = function(options) {
};
-function errnoException(errorno, syscall) {
+function errnoException(errorno, syscall, errmsg) {
// TODO make this more compatible with ErrnoException from src/node.cc
// Once all of Node is using this function the ErrnoException from
// src/node.cc should be removed.
- var e = new Error(syscall + ' ' + errorno);
+ var message = syscall + ' ' + errorno;
+ if (errmsg) {
+ message += ' - ' + errmsg;
+ }
+ var e = new Error(message);
e.errno = e.code = errorno;
e.syscall = syscall;
return e;
View
34 lib/dgram.js
@@ -223,7 +223,11 @@ Socket.prototype.address = function() {
Socket.prototype.setBroadcast = function(arg) {
- throw new Error('not yet implemented');
+ if (this._handle.setBroadcast((arg) ? 1 : 0) == -1) {
+ throw errnoException(errno, 'setBroadcast');
+ }
+
+ return true;
};
@@ -233,7 +237,11 @@ Socket.prototype.setTTL = function(arg) {
Socket.prototype.setMulticastTTL = function(arg) {
- throw new Error('not yet implemented');
+ if (this._handle.setMulticastTTL(arg) == -1) {
+ throw errnoException(errno, 'setMulticastTTL');
+ }
+
+ return true;
};
@@ -243,16 +251,26 @@ Socket.prototype.setMulticastLoopback = function(arg) {
Socket.prototype.addMembership = function(multicastAddress,
- multicastInterface) {
- // are we ever going to support this in libuv?
- throw new Error('not yet implemented');
+ interfaceAddress) {
+ this._healthCheck();
+
+ if (!multicastAddress) {
+ throw new Error('multicast address must be specified');
+ }
+
+ return this._handle.addMembership(multicastAddress, interfaceAddress);
};
Socket.prototype.dropMembership = function(multicastAddress,
- multicastInterface) {
- // are we ever going to support this in libuv?
- throw new Error('not yet implemented');
+ interfaceAddress) {
+ this._healthCheck();
+
+ if (!multicastAddress) {
+ throw new Error('multicast address must be specified');
+ }
+
+ return this._handle.dropMembership(multicastAddress, interfaceAddress);
};
View
22 lib/http.js
@@ -1181,13 +1181,23 @@ ClientRequest.prototype.onSocket = function(socket) {
// Setup "drain" propogation.
httpSocketSetup(socket);
+ var freeParser = function() {
+ if (parser) {
+ parsers.free(parser);
+ parser = null;
+ }
+ };
+
var errorListener = function(err) {
debug('HTTP SOCKET ERROR: ' + err.message + '\n' + err.stack);
req.emit('error', err);
// For Safety. Some additional errors might fire later on
// and we need to make sure we don't double-fire the error event.
req._hadError = true;
- parser.finish();
+ if (parser) {
+ parser.finish();
+ freeParser();
+ }
socket.destroy();
}
socket.on('error', errorListener);
@@ -1196,6 +1206,7 @@ ClientRequest.prototype.onSocket = function(socket) {
var ret = parser.execute(d, start, end - start);
if (ret instanceof Error) {
debug('parse error');
+ freeParser();
socket.destroy(ret);
} else if (parser.incoming && parser.incoming.upgrade) {
// Upgrade or CONNECT
@@ -1226,6 +1237,9 @@ ClientRequest.prototype.onSocket = function(socket) {
// Got Upgrade header or CONNECT method, but have no handler.
socket.destroy();
}
+ freeParser();
+ } else if (parser.incoming && parser.incoming.complete) {
+ freeParser();
}
};
@@ -1236,8 +1250,10 @@ ClientRequest.prototype.onSocket = function(socket) {
req.emit('error', createHangUpError());
req._hadError = true;
}
- parser.finish();
- parsers.free(parser); // I don't know if this is necessary --Mikeal
+ if (parser) {
+ parser.finish();
+ freeParser();
+ }
socket.destroy();
};
View
4 lib/path.js
@@ -62,7 +62,7 @@ if (isWindows) {
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/;
// Regex to split the tail part of the above into [*, dir, basename, ext]
- var splitTailRe = /^([\s\S]+[\\\/](?!$)|[\\\/])?((?:[\s\S]+?)?(\.[^.]*)?)$/;
+ var splitTailRe = /^([\s\S]+[\\\/](?!$)|[\\\/])?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/\\]*)?)$/;
// Function to split a filename into [root, dir, basename, ext]
// windows version
@@ -256,7 +256,7 @@ if (isWindows) {
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
- var splitPathRe = /^(\/?)([\s\S]+\/(?!$)|\/)?((?:[\s\S]+?)?(\.[^.]*)?)$/;
+ var splitPathRe = /^(\/?)([\s\S]+\/(?!$)|\/)?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/]*)?)$/;
var splitPath = function(filename) {
var result = splitPathRe.exec(filename);
return [result[1] || '', result[2] || '', result[3] || '', result[4] || ''];
View
19 lib/tls.js
@@ -271,7 +271,11 @@ CryptoStream.prototype._done = function() {
this.pair.encrypted._doneFlag &&
!this.pair._doneFlag) {
// If both streams are done:
- this.pair.destroy();
+ if (!this.pair._secureEstablished) {
+ this.pair.error();
+ } else {
+ this.pair.destroy();
+ }
}
};
@@ -724,7 +728,6 @@ SecurePair.prototype.destroy = function() {
}
var self = this;
- var error = this.ssl.error;
this._doneFlag = true;
this.ssl.error = null;
@@ -739,20 +742,18 @@ SecurePair.prototype.destroy = function() {
self.encrypted.emit('close');
self.cleartext.emit('close');
});
+};
+
+SecurePair.prototype.error = function() {
if (!this._secureEstablished) {
+ var error = this.ssl.error;
if (!error) {
error = new Error('socket hang up');
error.code = 'ECONNRESET';
}
- this.emit('error', error);
- }
-};
-
-
-SecurePair.prototype.error = function() {
- if (!this._secureEstablished) {
this.destroy();
+ this.emit('error', error);
} else {
var err = this.ssl.error;
this.ssl.error = null;
View
7 lib/tty.js
@@ -225,6 +225,13 @@ ReadStream.prototype._emitKey = function(s) {
case '[13~': key.name = 'f3'; break;
case '[14~': key.name = 'f4'; break;
+ /* from Cygwin and used in libuv */
+ case '[[A': key.name = 'f1'; break;
+ case '[[B': key.name = 'f2'; break;
+ case '[[C': key.name = 'f3'; break;
+ case '[[D': key.name = 'f4'; break;
+ case '[[E': key.name = 'f5'; break;
+
/* common */
case '[15~': key.name = 'f5'; break;
case '[17~': key.name = 'f6'; break;
View
27 lib/util.js
@@ -296,29 +296,28 @@ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
- var name, str;
- if (value.__lookupGetter__) {
- if (value.__lookupGetter__(key)) {
- if (value.__lookupSetter__(key)) {
- str = ctx.stylize('[Getter/Setter]', 'special');
- } else {
- str = ctx.stylize('[Getter]', 'special');
- }
+ var name, str, desc;
+ desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
+ if (desc.get) {
+ if (desc.set) {
+ str = ctx.stylize('[Getter/Setter]', 'special');
} else {
- if (value.__lookupSetter__(key)) {
- str = ctx.stylize('[Setter]', 'special');
- }
+ str = ctx.stylize('[Getter]', 'special');
+ }
+ } else {
+ if (desc.set) {
+ str = ctx.stylize('[Setter]', 'special');
}
}
if (visibleKeys.indexOf(key) < 0) {
name = '[' + key + ']';
}
if (!str) {
- if (ctx.seen.indexOf(value[key]) < 0) {
+ if (ctx.seen.indexOf(desc.value) < 0) {
if (recurseTimes === null) {
- str = formatValue(ctx, value[key], null);
+ str = formatValue(ctx, desc.value, null);
} else {
- str = formatValue(ctx, value[key], recurseTimes - 1);
+ str = formatValue(ctx, desc.value, recurseTimes - 1);
}
if (str.indexOf('\n') > -1) {
if (array) {
View
20 lib/zlib.js
@@ -122,18 +122,18 @@ function zlibBuffer(engine, buffer, callback) {
var buffers = [];
var nread = 0;
- engine.on('error', function(err) {
- engine.removeListener('end');
- engine.removeListener('error');
+ function onError(err) {
+ engine.removeListener('end', onEnd);
+ engine.removeListener('error', onError);
callback(err);
- });
+ }
- engine.on('data', function(chunk) {
+ function onData(chunk) {
buffers.push(chunk);
nread += chunk.length;
- });
+ }
- engine.on('end', function() {
+ function onEnd() {
var buffer;
switch(buffers.length) {
case 0:
@@ -153,7 +153,11 @@ function zlibBuffer(engine, buffer, callback) {
break;
}
callback(null, buffer);
- });
+ }
+
+ engine.on('error', onError);
+ engine.on('data', onData);
+ engine.on('end', onEnd);
engine.write(buffer);
engine.end();
View
1  src/node_crypto.cc
@@ -592,6 +592,7 @@ int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
if (rv >= 0) return rv;
int retry = BIO_should_retry(bio);
+ (void) retry; // unused if !defined(SSL_PRINT_DEBUG)
if (BIO_should_write(bio)) {
DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n", ssl_, func, retry);
View
73 src/udp_wrap.cc
@@ -92,6 +92,10 @@ class UDPWrap: public HandleWrap {
static Handle<Value> RecvStart(const Arguments& args);
static Handle<Value> RecvStop(const Arguments& args);
static Handle<Value> GetSockName(const Arguments& args);
+ static Handle<Value> AddMembership(const Arguments& args);
+ static Handle<Value> DropMembership(const Arguments& args);
+ static Handle<Value> SetMulticastTTL(const Arguments& args);
+ static Handle<Value> SetBroadcast(const Arguments& args);
private:
static inline char* NewSlab(v8::Handle<v8::Object> global, v8::Handle<v8::Object> wrap_obj);
@@ -101,6 +105,8 @@ class UDPWrap: public HandleWrap {
static Handle<Value> DoBind(const Arguments& args, int family);
static Handle<Value> DoSend(const Arguments& args, int family);
+ static Handle<Value> SetMembership(const Arguments& args,
+ uv_membership membership);
static uv_buf_t OnAlloc(uv_handle_t* handle, size_t suggested_size);
static void OnSend(uv_udp_send_t* req, int status);
@@ -148,6 +154,10 @@ void UDPWrap::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "recvStart", RecvStart);
NODE_SET_PROTOTYPE_METHOD(t, "recvStop", RecvStop);
NODE_SET_PROTOTYPE_METHOD(t, "getsockname", GetSockName);
+ NODE_SET_PROTOTYPE_METHOD(t, "addMembership", AddMembership);
+ NODE_SET_PROTOTYPE_METHOD(t, "dropMembership", DropMembership);
+ NODE_SET_PROTOTYPE_METHOD(t, "setMulticastTTL", SetMulticastTTL);
+ NODE_SET_PROTOTYPE_METHOD(t, "setBroadcast", SetBroadcast);
target->Set(String::NewSymbol("UDP"),
Persistent<FunctionTemplate>::New(t)->GetFunction());
@@ -204,6 +214,69 @@ Handle<Value> UDPWrap::Bind6(const Arguments& args) {
return DoBind(args, AF_INET6);
}
+Handle<Value> UDPWrap::SetBroadcast(const Arguments& args) {
+ HandleScope scope;
+ UNWRAP
+
+ assert(args.Length() == 1);
+
+ int on = args[0]->Uint32Value();
+ int r = uv_udp_set_broadcast(&wrap->handle_, on);
+
+ if (r)
+ SetErrno(uv_last_error(uv_default_loop()));
+
+ return scope.Close(Integer::New(r));
+}
+
+Handle<Value> UDPWrap::SetMembership(const Arguments& args,
+ uv_membership membership) {
+ HandleScope scope;
+ UNWRAP
+
+ assert(args.Length() == 2);
+
+ String::Utf8Value address(args[0]->ToString());
+ String::Utf8Value interface(args[1]->ToString());
+
+ const char* interface_cstr = *interface;
+ if (args[1]->IsUndefined() || args[1]->IsNull()) {
+ interface_cstr = NULL;
+ }
+
+ int r = uv_udp_set_membership(&wrap->handle_, *address, interface_cstr,
+ membership);
+
+ if (r)
+ SetErrno(uv_last_error(uv_default_loop()));
+
+ return scope.Close(Integer::New(r));
+}
+
+
+Handle<Value> UDPWrap::AddMembership(const Arguments& args) {
+ return SetMembership(args, UV_JOIN_GROUP);
+}
+
+
+Handle<Value> UDPWrap::DropMembership(const Arguments& args) {
+ return SetMembership(args, UV_LEAVE_GROUP);
+}
+
+Handle<Value> UDPWrap::SetMulticastTTL(const Arguments& args) {
+ HandleScope scope;
+ UNWRAP
+
+ assert(args.Length() == 1);
+
+ int ttl = args[0]->Uint32Value();
+ int r = uv_udp_set_multicast_ttl(&wrap->handle_, ttl);
+
+ if (r)
+ SetErrno(uv_last_error(uv_default_loop()));
+
+ return scope.Close(Integer::New(r));
+}
Handle<Value> UDPWrap::DoSend(const Arguments& args, int family) {
HandleScope scope;
View
15 src/v8_typed_array.cc
@@ -141,6 +141,7 @@ class TypedArray {
v8::HandleScope scope;
ft_cache = v8::Persistent<v8::FunctionTemplate>::New(
v8::FunctionTemplate::New(&TypedArray<TBytes, TEAType>::V8New));
+ ft_cache->SetClassName(v8::String::New(TypeName()));
v8::Local<v8::ObjectTemplate> instance = ft_cache->InstanceTemplate();
instance->SetInternalFieldCount(0);
@@ -434,6 +435,20 @@ class TypedArray {
return TypedArray<TBytes, TEAType>::GetTemplate()->
GetFunction()->NewInstance(3, argv);
}
+
+ static const char* TypeName() {
+ switch (TEAType) {
+ case v8::kExternalByteArray: return "Int8Array";
+ case v8::kExternalUnsignedByteArray: return "Uint8Array";
+ case v8::kExternalShortArray: return "Int16Array";
+ case v8::kExternalUnsignedShortArray: return "Uint16Array";
+ case v8::kExternalIntArray: return "Int32Array";
+ case v8::kExternalUnsignedIntArray: return "Uint32Array";
+ case v8::kExternalFloatArray: return "Float32Array";
+ case v8::kExternalDoubleArray: return "Float64Array";
+ }
+ abort();
+ }
};
class Int8Array : public TypedArray<1, v8::kExternalByteArray> { };
View
2  test/common.js
@@ -55,7 +55,7 @@ exports.indirectInstanceOf = function(obj, cls) {
exports.ddCommand = function(filename, kilobytes) {
if (process.platform == 'win32') {
return '"' + process.argv[0] + '" "' + path.resolve(exports.fixturesDir,
- 'create-file.js') + '" "' + filename + '" ' + (kilobytes * 1024);
+ 'create-file.js') + '" "' + filename + '" ' + (kilobytes * 1024);
} else {
return 'dd if=/dev/zero of="' + filename + '" bs=1024 count=' + kilobytes;
}
View
4 test/internet/test-dns.js
@@ -383,11 +383,11 @@ TEST(function test_lookup_localhost_ipv4(done) {
var getaddrinfoCallbackCalled = false;
-console.log("looking up nodejs.org...");
+console.log('looking up nodejs.org...');
var req = process.binding('cares_wrap').getaddrinfo('nodejs.org');
req.oncomplete = function(domains) {
- console.log("nodejs.org = ", domains);
+ console.log('nodejs.org = ', domains);
assert.ok(Array.isArray(domains));
assert.ok(domains.length >= 1);
assert.ok(typeof domains[0] == 'string');
View
2  test/message/throw_custom_error.js
@@ -28,6 +28,6 @@ var assert = require('assert');
common.error('before');
// custom error throwing
-throw { name: 'MyCustomError', message: 'This is a custom message' }
+throw { name: 'MyCustomError', message: 'This is a custom message' };
common.error('after');
View
2  test/message/throw_non_error.js
@@ -28,6 +28,6 @@ var assert = require('assert');
common.error('before');
// custom error throwing
-throw { foo: 'bar' }
+throw { foo: 'bar' };
common.error('after');
View
14 test/pummel/test-net-timeout2.js
@@ -32,12 +32,12 @@ var counter = 0;
var server = net.createServer(function(socket) {
socket.setTimeout((seconds / 2) * 1000, function() {
gotTimeout = true;
- console.log('timeout!!');
- socket.destroy();
+ console.log('timeout!!');
+ socket.destroy();
process.exit(1);
- });
+ });
- var interval = setInterval(function() {
+ var interval = setInterval(function() {
counter++;
if (counter == seconds) {
@@ -46,9 +46,9 @@ var server = net.createServer(function(socket) {
socket.destroy();
}
- if (socket.writable) {
- socket.write(Date.now()+'\n');
- }
+ if (socket.writable) {
+ socket.write(Date.now() + '\n');
+ }
}, 1000);
});
View
2  test/simple/test-assert.js
@@ -214,7 +214,7 @@ threw = false;
try {
assert.throws(
function() {
- throw {}
+ throw {};
},
Array
);
View
15 test/simple/test-child-process-double-pipe.js
@@ -28,11 +28,16 @@ var assert = require('assert'),
// We're trying to reproduce:
// $ echo "hello\nnode\nand\nworld" | grep o | sed s/o/a/
-var echo = is_windows ? spawn('cmd.exe', ['/c', 'echo', 'hello&&', 'echo',
- 'node&&', 'echo', 'and&&', 'echo', 'world']) :
- spawn('echo', ['hello\nnode\nand\nworld\n']),
- grep = spawn('grep', ['o']),
- sed = spawn('sed', ['s/o/O/']);
+var grep = spawn('grep', ['o']),
+ sed = spawn('sed', ['s/o/O/']),
+ echo;
+
+if (is_windows) {
+ echo = spawn('cmd.exe', ['/c', 'echo', 'hello&&', 'echo',
+ 'node&&', 'echo', 'and&&', 'echo', 'world']);
+} else {
+ echo = spawn('echo', ['hello\nnode\nand\nworld\n']);
+}
/*
* grep and sed hang if the spawn function leaks file descriptors to child
View
6 test/simple/test-child-process-fork2.js
@@ -51,12 +51,12 @@ server.listen(common.PORT, function() {
function makeConnections() {
for (var i = 0; i < N; i++) {
var socket = net.connect(common.PORT, function() {
- console.log("CLIENT connected");
+ console.log('CLIENT connected');
});
- socket.on("close", function() {
+ socket.on('close', function() {
socketCloses++;
- console.log("CLIENT closed " + socketCloses);
+ console.log('CLIENT closed ' + socketCloses);
if (socketCloses == N) {
n.kill();
server.close();
View
59 test/simple/test-cluster-uncaught-exception.js
@@ -0,0 +1,59 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// 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.
+
+// Installing a custom uncaughtException handler should override the default
+// one that the cluster module installs.
+// https://github.com/joyent/node/issues/2556
+
+var common = require('../common');
+var assert = require('assert');
+var cluster = require('cluster');
+var fork = require('child_process').fork;
+
+var MAGIC_EXIT_CODE = 42;
+
+var isTestRunner = process.argv[2] != 'child';
+
+if (isTestRunner) {
+ var exitCode = -1;
+
+ process.on('exit', function() {
+ assert.equal(exitCode, MAGIC_EXIT_CODE);
+ });
+
+ var master = fork(__filename, ['child']);
+ master.on('exit', function(code) {
+ exitCode = code;
+ });
+}
+else if (cluster.isMaster) {
+ process.on('uncaughtException', function() {
+ process.nextTick(function() {
+ process.exit(MAGIC_EXIT_CODE);
+ });
+ });
+
+ cluster.fork();
+ throw new Error('kill master');
+}
+else { // worker
+ process.exit();
+}
View
9 test/simple/test-crypto-ecb.js
@@ -35,17 +35,16 @@ try {
// Testing whether EVP_CipherInit_ex is functioning correctly.
// Reference: bug#1997
-(function()
-{
+(function() {
var encrypt = crypto.createCipheriv('BF-ECB', 'SomeRandomBlahz0c5GZVnR', '');
var hex = encrypt.update('Hello World!', 'ascii', 'hex');
hex += encrypt.final('hex');
assert.equal(hex.toUpperCase(), '6D385F424AAB0CFBF0BB86E07FFB7D71');
}());
-(function()
-{
- var decrypt = crypto.createDecipheriv('BF-ECB', 'SomeRandomBlahz0c5GZVnR', '');
+(function() {
+ var decrypt = crypto.createDecipheriv('BF-ECB', 'SomeRandomBlahz0c5GZVnR',
+ '');
var msg = decrypt.update('6D385F424AAB0CFBF0BB86E07FFB7D71', 'hex', 'ascii');
msg += decrypt.final('ascii');
assert.equal(msg, 'Hello World!');
View
160 test/simple/test-dgram-broadcast-multi-process.js
@@ -0,0 +1,160 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// 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.
+
+var common = require('../common'),
+ assert = require('assert'),
+ cluster = require('cluster'),
+ dgram = require('dgram'),
+ util = require('util'),
+ assert = require('assert'),
+ Buffer = require('buffer').Buffer,
+ LOCAL_BROADCAST_HOST = '255.255.255.255',
+ messages = [
+ new Buffer('First message to send'),
+ new Buffer('Second message to send'),
+ new Buffer('Third message to send'),
+ new Buffer('Fourth message to send')
+ ];
+
+if (cluster.isMaster) {
+ var workers = {},
+ listeners = 3,
+ listening = 0,
+ i = 0,
+ done = 0;
+
+ //launch child processes
+ for (var x = 0; x < listeners; x++) {
+ (function () {
+ var worker = cluster.fork();
+ workers[worker.pid] = worker;
+
+ worker.messagesReceived = [];
+
+ worker.on('message', function (msg) {
+ if (msg.listening) {
+ listening += 1;
+
+ if (listening === listeners) {
+ //all child process are listening, so start sending
+ sendSocket.sendNext();
+ }
+ }
+ else if (msg.message) {
+ worker.messagesReceived.push(msg.message);
+
+ if (worker.messagesReceived.length === messages.length) {
+ done += 1;
+ console.error('%d received %d messages total.', worker.pid,
+ worker.messagesReceived.length);
+ }
+
+ if (done === listeners) {
+ console.error('All workers have received the required number of '
+ + 'messages. Will now compare.');
+
+ Object.keys(workers).forEach(function (pid) {
+ var worker = workers[pid];
+
+ var count = 0;
+
+ worker.messagesReceived.forEach(function(buf) {
+ for (var i = 0; i < messages.length; ++i) {
+ if (buf.toString() === messages[i].toString()) {
+ count++;
+ break;
+ }
+ }
+ });
+
+ console.error('%d received %d matching messges.', worker.pid
+ , count);
+
+ assert.equal(count, messages.length
+ ,'A worker received an invalid multicast message');
+ });
+ }
+ }
+ });
+ })(x);
+ }
+
+ var sendSocket = dgram.createSocket('udp4');
+
+ sendSocket.bind(common.PORT);
+ sendSocket.setBroadcast(true);
+
+ sendSocket.on('close', function() {
+ console.error('sendSocket closed');
+ });
+
+ sendSocket.sendNext = function() {
+ var buf = messages[i++];
+
+ if (!buf) {
+ try { sendSocket.close(); } catch (e) {}
+ return;
+ }
+
+ sendSocket.send(buf, 0, buf.length,
+ common.PORT, LOCAL_BROADCAST_HOST, function(err) {
+
+ if (err) throw err;
+
+ console.error('sent %s to %s:%s', util.inspect(buf.toString())
+ , LOCAL_BROADCAST_HOST, common.PORT);
+
+ process.nextTick(sendSocket.sendNext);
+ });
+ };
+}
+
+if (!cluster.isMaster) {
+ var receivedMessages = [];
+ var listenSocket = dgram.createSocket('udp4');
+
+ listenSocket.on('message', function(buf, rinfo) {
+ console.error('%s received %s from %j', process.pid
+ , util.inspect(buf.toString()), rinfo);
+
+ receivedMessages.push(buf);
+
+ process.send({ message : buf.toString() });
+
+ if (receivedMessages.length == messages.length) {
+ listenSocket.dropMembership(LOCAL_BROADCAST_HOST);
+ process.nextTick(function() { // TODO should be changed to below.
+ // listenSocket.dropMembership(LOCAL_BROADCAST_HOST, function() {
+ listenSocket.close();
+ });
+ }
+ });
+
+ listenSocket.on('close', function() {
+ process.exit();
+ });
+
+ listenSocket.on('listening', function() {
+ process.send({ listening : true });
+ });
+
+ listenSocket.bind(common.PORT);
+}
View
160 test/simple/test-dgram-multicast-multi-process.js
@@ -0,0 +1,160 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// 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.
+
+var common = require('../common'),
+ assert = require('assert'),
+ cluster = require('cluster'),
+ dgram = require('dgram'),
+ util = require('util'),
+ assert = require('assert'),
+ Buffer = require('buffer').Buffer,
+ LOCAL_BROADCAST_HOST = '224.0.0.1',
+ messages = [
+ new Buffer('First message to send'),
+ new Buffer('Second message to send'),
+ new Buffer('Third message to send'),
+ new Buffer('Fourth message to send')
+ ];
+
+if (cluster.isMaster) {
+ var workers = {},
+ listeners = 3,
+ listening = 0,
+ i = 0,
+ done = 0;
+
+ //launch child processes
+ for (var x = 0; x < listeners; x++) {
+ (function () {
+ var worker = cluster.fork();
+ workers[worker.pid] = worker;
+
+ worker.messagesReceived = [];
+
+ worker.on('message', function (msg) {
+ if (msg.listening) {
+ listening += 1;
+
+ if (listening === listeners) {
+ //all child process are listening, so start sending
+ sendSocket.sendNext();
+ }
+ }
+ else if (msg.message) {
+ worker.messagesReceived.push(msg.message);
+
+ if (worker.messagesReceived.length === messages.length) {
+ done += 1;
+ console.error('%d received %d messages total.', worker.pid,
+ worker.messagesReceived.length);
+ }
+
+ if (done === listeners) {
+ console.error('All workers have received the required number of'
+ + 'messages. Will now compare.');
+
+ Object.keys(workers).forEach(function (pid) {
+ var worker = workers[pid];
+
+ var count = 0;
+
+ worker.messagesReceived.forEach(function(buf) {
+ for (var i = 0; i < messages.length; ++i) {
+ if (buf.toString() === messages[i].toString()) {
+ count++;
+ break;
+ }
+ }
+ });
+
+ console.error('%d received %d matching messges.', worker.pid
+ , count);
+
+ assert.equal(count, messages.length
+ ,'A worker received an invalid multicast message');
+ });
+ }
+ }
+ });
+ })(x);
+ }
+
+ var sendSocket = dgram.createSocket('udp4');
+
+ //sendSocket.setBroadcast(true);
+ //sendSocket.setMulticastTTL(1);
+ //sendSocket.setMulticastLoopback(true);
+
+ sendSocket.on('close', function() {
+ console.error('sendSocket closed');
+ });
+
+ sendSocket.sendNext = function() {
+ var buf = messages[i++];
+
+ if (!buf) {
+ try { sendSocket.close(); } catch (e) {}
+ return;
+ }
+
+ sendSocket.send(buf, 0, buf.length,
+ common.PORT, LOCAL_BROADCAST_HOST, function(err) {
+ if (err) throw err;
+ console.error('sent %s to %s', util.inspect(buf.toString()),
+ LOCAL_BROADCAST_HOST + common.PORT);
+ process.nextTick(sendSocket.sendNext);
+ });
+ };
+}
+
+if (!cluster.isMaster) {
+ var receivedMessages = [];
+ var listenSocket = dgram.createSocket('udp4');
+
+ listenSocket.addMembership(LOCAL_BROADCAST_HOST);
+
+ listenSocket.on('message', function(buf, rinfo) {
+ console.error('%s received %s from %j', process.pid
+ ,util.inspect(buf.toString()), rinfo);
+
+ receivedMessages.push(buf);
+
+ process.send({ message : buf.toString() });
+
+ if (receivedMessages.length == messages.length) {
+ listenSocket.dropMembership(LOCAL_BROADCAST_HOST);
+ process.nextTick(function() { // TODO should be changed to below.
+ // listenSocket.dropMembership(LOCAL_BROADCAST_HOST, function() {
+ listenSocket.close();
+ });
+ }
+ });
+
+ listenSocket.on('close', function() {
+ process.exit();
+ });
+
+ listenSocket.on('listening', function() {
+ process.send({ listening : true });
+ });
+
+ listenSocket.bind(common.PORT);
+}
View
41 test/simple/test-dgram-multicast-setTTL.js
@@ -0,0 +1,41 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// 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.
+
+var common = require('../common'),
+ assert = require('assert'),
+ dgram = require('dgram'),
+ thrown = false,
+ socket = dgram.createSocket('udp4');
+
+socket.bind(common.PORT);
+socket.setMulticastTTL(16);
+
+//Try to set an invalid TTL (valid ttl is > 0 and < 256)
+try {
+ socket.setMulticastTTL(1000);
+} catch (e) {
+ thrown = true;
+}
+
+assert(thrown, 'Setting an invalid mutlicast TTL should throw some error');
+
+//close the socket
+socket.close();
View
4 test/simple/test-dgram-send-error.js
@@ -73,9 +73,9 @@ function doSend() {
}
process.on('exit', function() {
- console.log(packetsSent + ' UDP packets sent, ' +
+ console.log(packetsSent + ' UDP packets sent, ' +
packetsReceived + ' received');
-
+
assert.strictEqual(packetsSent, ITERATIONS * 2);
assert.strictEqual(packetsReceived, ITERATIONS);
});
View
4 test/simple/test-eval.js
@@ -30,8 +30,8 @@ var exec = require('child_process').exec;
var success_count = 0;
var error_count = 0;
-var cmd = [process.execPath, '-e', '"console.error(process.argv)"', 'foo', 'bar']
- .join(' ');
+var cmd = [process.execPath, '-e', '"console.error(process.argv)"',
+ 'foo', 'bar'].join(' ');
var expected = util.format([process.execPath, 'foo', 'bar']) + '\n';
var child = exec(cmd, function(err, stdout, stderr) {
if (err) {
View
16 test/simple/test-executable-path.js
@@ -26,14 +26,14 @@ var match = false;
var isDebug = process.features.debug;
-var debugPaths = [ path.normalize(path.join(__dirname, '..', '..',
- 'out', 'Debug', 'node')),
- path.normalize(path.join(__dirname, '..', '..',
- 'Debug', 'node'))];
-var defaultPaths = [ path.normalize(path.join(__dirname, '..', '..',
- 'out', 'Release', 'node')),
- path.normalize(path.join(__dirname, '..', '..',
- 'Release', 'node'))];
+var debugPaths = [path.normalize(path.join(__dirname, '..', '..',
+ 'out', 'Debug', 'node')),
+ path.normalize(path.join(__dirname, '..', '..',
+ 'Debug', 'node'))];
+var defaultPaths = [path.normalize(path.join(__dirname, '..', '..',
+ 'out', 'Release', 'node')),
+ path.normalize(path.join(__dirname, '..', '..',
+ 'Release', 'node'))];
console.error('debugPaths: ' + debugPaths);
console.error('defaultPaths: ' + defaultPaths);
View
6 test/simple/test-fs-long-path.js
@@ -31,8 +31,10 @@ var fileNameLen = Math.max(260 - common.tmpDir.length - 1, 1);
var fileName = path.join(common.tmpDir, new Array(fileNameLen + 1).join('x'));
var fullPath = path.resolve(fileName);
-console.log({ filenameLength: fileName.length,
- fullPathLength: fullPath.length });
+console.log({
+ filenameLength: fileName.length,
+ fullPathLength: fullPath.length
+});
fs.writeFile(fullPath, 'ok', function(err) {
if (err) throw err;
View
2  test/simple/test-fs-mkdir.js
@@ -80,4 +80,4 @@ function unlink(pathname) {
// Keep the event loop alive so the async mkdir() requests
// have a chance to run (since they don't ref the event loop).
-process.nextTick(function(){});
+process.nextTick(function() {});
View
10 test/simple/test-fs-symlink.js
@@ -38,8 +38,7 @@ var runtest = function(skip_symlinks) {
// Delete previously created link
try {
fs.unlinkSync(linkPath);
- } catch(e)
- {}
+ } catch (e) {}
fs.symlink(linkData, linkPath, function(err) {
if (err) throw err;
@@ -60,8 +59,7 @@ var runtest = function(skip_symlinks) {
// Delete previously created link
try {
fs.unlinkSync(dstPath);
- } catch(e)
- {}
+ } catch (e) {}
fs.link(srcPath, dstPath, function(err) {
if (err) throw err;
@@ -71,12 +69,12 @@ var runtest = function(skip_symlinks) {
assert.equal(srcContent, dstContent);
completed++;
});
-}
+};
if (is_windows) {
// On Windows, creating symlinks requires admin privileges.
// We'll only try to run symlink test if we have enough privileges.
- exec("whoami /priv", function(err, o) {
+ exec('whoami /priv', function(err, o) {
if (err || o.indexOf('SeCreateSymbolicLinkPrivilege') == -1) {
expected_tests = 1;
runtest(true);
View
10 test/simple/test-fs-utimes.js
@@ -68,7 +68,7 @@ function expect_ok(syscall, resource, err, atime, mtime) {
// the tests assume that __filename belongs to the user running the tests
// this should be a fairly safe assumption; testing against a temp file
// would be even better though (node doesn't have such functionality yet)
-function runTests(atime, mtime, callback) {
+function runTest(atime, mtime, callback) {
var fd, err;
//
@@ -144,10 +144,10 @@ function runTests(atime, mtime, callback) {
var stats = fs.statSync(__filename);
-runTests(new Date('1982-09-10 13:37'), new Date('1982-09-10 13:37'), function() {
- runTests(new Date(), new Date(), function() {
- runTests(123456.789, 123456.789, function() {
- runTests(stats.mtime, stats.mtime, function() {
+runTest(new Date('1982-09-10 13:37'), new Date('1982-09-10 13:37'), function() {
+ runTest(new Date(), new Date(), function() {
+ runTest(123456.789, 123456.789, function() {
+ runTest(stats.mtime, stats.mtime, function() {
// done
});
});
View
6 test/simple/test-http-1.0.js
@@ -112,7 +112,8 @@ function test(handler, request_generator, response_validator) {
function request_generator() {
return ('GET / HTTP/1.0\r\n' +
- 'User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15\r\n' +
+ 'User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 ' +
+ 'OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15\r\n' +
'Host: 127.0.0.1:1337\r\n' +
'Accept: */*\r\n' +
'\r\n');
@@ -147,7 +148,8 @@ function test(handler, request_generator, response_validator) {
function request_generator() {
return ('GET / HTTP/1.1\r\n' +
- 'User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15\r\n' +
+ 'User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 ' +
+ 'OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15\r\n' +
'Connection: close\r\n' +
'Host: 127.0.0.1:1337\r\n' +
'Accept: */*\r\n' +
View
2  test/simple/test-http-abort-before-end.js
@@ -28,7 +28,7 @@ var server = http.createServer(function(req, res) {
});
server.listen(common.PORT, function() {
- var req = http.request({method:'GET', host:'127.0.0.1', port:common.PORT});
+ var req = http.request({method: 'GET', host: '127.0.0.1', port: common.PORT});
req.on('error', function(ex) {
// https://github.com/joyent/node/issues/1399#issuecomment-2597359
View
54 test/simple/test-http-parser-free.js
@@ -0,0 +1,54 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// 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.
+
+var common = require('../common');
+var assert = require('assert');
+var http = require('http');
+var N = 100;
+var responses = 0;
+
+var server = http.createServer(function(req, res) {
+ res.end('Hello');
+});
+
+server.listen(common.PORT, function() {
+ http.globalAgent.maxSockets = 1;
+ var parser;
+ for (var i = 0; i < N; ++i) {
+ (function makeRequest(i) {
+ var req = http.get({port: common.PORT}, function(res) {
+ if (!parser) {
+ parser = req.parser;
+ } else {
+ assert.strictEqual(req.parser, parser);
+ }
+
+ if (++responses === N) {
+ server.close();
+ }
+ });
+ })(i);
+ }
+});
+
+process.on('exit', function() {
+ assert.equal(responses, N);
+});
View
6 test/simple/test-http-res-write-end-dont-take-array.js
@@ -25,7 +25,7 @@ var http = require('http');
var test = 1;
-var server = http.createServer(function (req, res) {
+var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
if (test === 1) {
// write should accept string
@@ -53,11 +53,11 @@ var server = http.createServer(function (req, res) {
server.listen(common.PORT, function() {
// just make a request, other tests handle responses
- http.get({port:common.PORT}, function() {
+ http.get({port: common.PORT}, function() {
// lazy serial test, becuase we can only call end once per request
test += 1;
// do it again to test .end(Buffer);
- http.get({port:common.PORT}, function() {
+ http.get({port: common.PORT}, function() {
server.close();
});
});
View
9 test/simple/test-http-response-no-headers.js
@@ -27,8 +27,8 @@ var net = require('net');
var expected = {
'0.9': 'I AM THE WALRUS',
'1.0': 'I AM THE WALRUS',
- '1.1': '',
-}
+ '1.1': ''
+};
var gotExpected = false;
@@ -38,11 +38,12 @@ function test(httpVersion, callback) {
});
var server = net.createServer(function(conn) {
- var reply = 'HTTP/' + httpVersion + ' 200 OK\r\n\r\n' + expected[httpVersion];
+ var reply = 'HTTP/' + httpVersion + ' 200 OK\r\n\r\n' +
+ expected[httpVersion];
conn.write(reply, function() {
conn.destroy();
- })
+ });
});
server.listen(common.PORT, '127.0.0.1', function() {
View
71 test/simple/test-http-should-keep-alive.js
@@ -0,0 +1,71 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// 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.
+
+var common = require('../common');
+var assert = require('assert');
+var http = require('http');
+var net = require('net');
+
+var SERVER_RESPONSES = [
+ 'HTTP/1.0 200 ok\r\nContent-Length: 0\r\n\r\n',
+ 'HTTP/1.0 200 ok\r\nContent-Length: 0\r\nConnection: keep-alive\r\n\r\n',
+ 'HTTP/1.0 200 ok\r\nContent-Length: 0\r\nConnection: close\r\n\r\n',
+ 'HTTP/1.1 200 ok\r\nContent-Length: 0\r\n\r\n',
+ 'HTTP/1.1 200 ok\r\nContent-Length: 0\r\nConnection: keep-alive\r\n\r\n',
+ 'HTTP/1.1 200 ok\r\nContent-Length: 0\r\nConnection: close\r\n\r\n',
+];
+var SHOULD_KEEP_ALIVE = [
+ false, // HTTP/1.0, default
+ true, // HTTP/1.0, Connection: keep-alive
+ false, // HTTP/1.0, Connection: close
+ true, // HTTP/1.1, default
+ true, // HTTP/1.1, Connection: keep-alive
+ false, // HTTP/1.1, Connection: close
+];
+var requests = 0;
+var responses = 0;
+
+var server = net.createServer(function(socket) {
+ socket.write(SERVER_RESPONSES[requests]);
+ ++requests;
+}).listen(common.PORT, function() {
+ function makeRequest() {
+ var req = http.get({port: common.PORT}, function(res) {
+ assert.equal(req.shouldKeepAlive, SHOULD_KEEP_ALIVE[responses],
+ SERVER_RESPONSES[responses] + ' should ' +
+ (SHOULD_KEEP_ALIVE[responses] ? '' : 'not ') +
+ 'Keep-Alive');
+ ++responses;
+ if (responses < SHOULD_KEEP_ALIVE.length) {
+ makeRequest();
+ } else {
+ server.close();
+ }
+ });
+ }
+
+ makeRequest();
+});
+
+process.on('exit', function() {
+ assert.equal(requests, SERVER_RESPONSES.length);
+ assert.equal(responses, SHOULD_KEEP_ALIVE.length);
+});
View
15 test/simple/test-init.js
@@ -36,11 +36,13 @@
child.exec(process.execPath + ' test-init', {env: {'TEST_INIT': 1}},
function(err, stdout, stderr) {
- assert.equal(stdout, 'Loaded successfully!', '`node test-init` failed!');
+ assert.equal(stdout, 'Loaded successfully!',
+ '`node test-init` failed!');
});
child.exec(process.execPath + ' test-init.js', {env: {'TEST_INIT': 1}},
function(err, stdout, stderr) {
- assert.equal(stdout, 'Loaded successfully!', '`node test-init.js` failed!');
+ assert.equal(stdout, 'Loaded successfully!',
+ '`node test-init.js` failed!');
});
// test-init-index is in fixtures dir as requested by ry, so go there
@@ -48,16 +50,19 @@
child.exec(process.execPath + ' test-init-index', {env: {'TEST_INIT': 1}},
function(err, stdout, stderr) {
- assert.equal(stdout, 'Loaded successfully!', '`node test-init-index failed!');
+ assert.equal(stdout, 'Loaded successfully!',
+ '`node test-init-index failed!');
});
// ensures that `node fs` does not mistakenly load the native 'fs' module
- // instead of the desired file and that the fs module loads as expected in node
+ // instead of the desired file and that the fs module loads as
+ // expected in node
process.chdir(common.fixturesDir + '/test-init-native/');
child.exec(process.execPath + ' fs', {env: {'TEST_INIT': 1}},
function(err, stdout, stderr) {
- assert.equal(stdout, 'fs loaded successfully', '`node fs` failed!');
+ assert.equal(stdout, 'fs loaded successfully',
+ '`node fs` failed!');
});
}
})();
View
13 test/simple/test-module-load-list.js
@@ -24,19 +24,20 @@
// beginning of this file.
function assertEqual(x, y) {
- if (x !== y) throw new Error("Expected '" + x + "' got '" + y + "'");
+ if (x !== y) throw new Error('Expected \'' + x + '\' got \'' + y + '\'');
}
function checkExpected() {
var toCompare = Math.max(expected.length, process.moduleLoadList.length);
for (var i = 0; i < toCompare; i++) {
if (expected[i] !== process.moduleLoadList[i]) {
- console.error("process.moduleLoadList[" + i + "] = " + process.moduleLoadList[i]);
- console.error("expected[" + i + "] = " + expected[i]);
+ console.error('process.moduleLoadList[' + i + '] = ' +
+ process.moduleLoadList[i]);
+ console.error('expected[' + i + '] = ' + expected[i]);
- console.error("process.moduleLoadList", process.moduleLoadList);
- console.error("expected = ", expected);
- throw new Error("mismatch");
+ console.error('process.moduleLoadList', process.moduleLoadList);
+ console.error('expected = ', expected);
+ throw new Error('mismatch');
}
}
}
View
2  test/simple/test-net-connect-buffer.js
@@ -85,7 +85,7 @@ tcp.listen(common.PORT, function() {
// Write a string that contains a multi-byte character sequence to test that
// `bytesWritten` is incremented with the # of bytes, not # of characters.
var a = "L'État, c'est ";
- var b = "moi";
+ var b = 'moi';
// We're still connecting at this point so the datagram is first pushed onto
// the connect queue. Make sure that it's not added to `bytesWritten` again
View
26 test/simple/test-net-pipe-connect-errors.js
@@ -31,42 +31,40 @@ var accessErrorFired = false;
// Test if ENOTSOCK is fired when trying to connect to a file which is not
// a socket.
-var notSocketClient = net.createConnection(
- path.join(common.fixturesDir, 'empty.txt'),
- function () {
- assert.ok(false);
- }
-);
+var emptyTxt = path.join(common.fixturesDir, 'empty.txt');
+var notSocketClient = net.createConnection(emptyTxt, function() {
+ assert.ok(false);
+});
-notSocketClient.on('error', function (err) {
+notSocketClient.on(<