Browse Source

Merge branch 'v0.4'

Conflicts:
	src/node_crypto.cc
v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
85bc8d02fa
  1. 15
      doc/api/dns.markdown
  2. 24
      doc/api/http.markdown
  3. 51
      doc/api/modules.markdown
  4. 16
      doc/api/net.markdown
  5. 4
      doc/index.html
  6. BIN
      doc/trademark-policy.pdf
  7. 2
      lib/dns.js
  8. 6
      lib/events.js
  9. 12
      lib/http.js
  10. 6
      lib/tls.js
  11. 45
      lib/url.js
  12. 1
      src/node.cc
  13. 13
      src/node_crypto.cc
  14. 15
      test/simple/test-buffer.js
  15. 6
      test/simple/test-c-ares.js
  16. 29
      test/simple/test-event-emitter-check-listener-leaks.js
  17. 44
      test/simple/test-http-request-aborted.js
  18. 9
      test/simple/test-http-set-timeout.js
  19. 53
      test/simple/test-https-request-aborted.js
  20. 53
      test/simple/test-https-request-timeout.js
  21. 50
      test/simple/test-tls-request-timeout.js
  22. 26
      test/simple/test-url.js

15
doc/api/dns.markdown

@ -41,7 +41,8 @@ necessarily the value initially passed to `lookup`).
Resolves a domain (e.g. `'google.com'`) into an array of the record types Resolves a domain (e.g. `'google.com'`) into an array of the record types
specified by rrtype. Valid rrtypes are `A` (IPV4 addresses), `AAAA` (IPV6 specified by rrtype. Valid rrtypes are `A` (IPV4 addresses), `AAAA` (IPV6
addresses), `MX` (mail exchange records), `TXT` (text records), `SRV` (SRV addresses), `MX` (mail exchange records), `TXT` (text records), `SRV` (SRV
records), and `PTR` (used for reverse IP lookups). records), `PTR` (used for reverse IP lookups), `NS` (name server records)
and `CNAME` (canonical name records).
The callback has arguments `(err, addresses)`. The type of each item The callback has arguments `(err, addresses)`. The type of each item
in `addresses` is determined by the record type, and described in the in `addresses` is determined by the record type, and described in the
@ -89,6 +90,18 @@ Reverse resolves an ip address to an array of domain names.
The callback has arguments `(err, domains)`. The callback has arguments `(err, domains)`.
### dns.resolveNs(domain, callback)
The same as `dns.resolve()`, but only for name server records (`NS` records).
`addresses` is an array of the name server records available for `domain`
(e.g., `['ns1.example.com', 'ns2.example.com']`).
### dns.resolveCname(domain, callback)
The same as `dns.resolve()`, but only for canonical name records (`CNAME`
records). `addresses` is an array of the canonical name records available for
`domain` (e.g., `['bar.example.com']`).
If there an an error, `err` will be non-null and an instanceof the Error If there an an error, `err` will be non-null and an instanceof the Error
object. object.

24
doc/api/http.markdown

@ -142,9 +142,29 @@ body chunk is a string. The body encoding is set with
`function () { }` `function () { }`
Emitted exactly once for each message. No arguments. After Emitted exactly once for each request. After that, no more `'data'` events
emitted no other events will be emitted on the request. will be emitted on the request.
### Event: 'close'
`function (err) { }`
Indicates that the underlaying connection was terminated before
`response.end()` was called or able to flush.
The `err` parameter is always present and indicates the reason for the timeout:
`err.code === 'timeout'` indicates that the underlaying connection timed out.
This may happen because all incoming connections have a default timeout of 2
minutes.
`err.code === 'aborted'` means that the client has closed the underlaying
connection prematurely.
Just like `'end'`, this event occurs only once per request, and no more `'data'`
events will fire afterwards.
Note: `'close'` can fire after `'end'`, but not vice versa.
### request.method ### request.method

51
doc/api/modules.markdown

@ -139,6 +139,22 @@ Modules are cached after the first time they are loaded. This means
(among other things) that every call to `require('foo')` will get (among other things) that every call to `require('foo')` will get
exactly the same object returned, if it would resolve to the same file. exactly the same object returned, if it would resolve to the same file.
Multiple calls to `require('foo')` may not cause the module code to be
executed multiple times. This is an important feature. With it,
"partially done" objects can be returned, thus allowing transitive
dependencies to be loaded even when they would cause cycles.
If you want to have a module execute code multiple times, then export a
function, and call that function.
#### Module Caching Caveats
Modules are cached based on their resolved filename. Since modules may
resolve to a different filename based on the location of the calling
module (loading from `node_modules` folders), it is not a *guarantee*
that `require('foo')` will always return the exact same object, if it
would resolve to different files.
### module.exports ### module.exports
The `exports` object is created by the Module system. Sometimes this is not The `exports` object is created by the Module system. Sometimes this is not
@ -173,17 +189,12 @@ x.js:
module.exports = { a: "hello" }; module.exports = { a: "hello" };
}, 0); }, 0);
y.js y.js:
var x = require('./x'); var x = require('./x');
console.log(x.a); console.log(x.a);
### All Together... ### All Together...
To get the exact filename that will be loaded when `require()` is called, use To get the exact filename that will be loaded when `require()` is called, use
@ -192,11 +203,11 @@ the `require.resolve()` function.
Putting together all of the above, here is the high-level algorithm Putting together all of the above, here is the high-level algorithm
in pseudocode of what require.resolve does: in pseudocode of what require.resolve does:
require(X) require(X) from module at path Y
1. If X is a core module, 1. If X is a core module,
a. return the core module a. return the core module
b. STOP b. STOP
2. If X begins with `./` or `/`, 2. If X begins with './' or '/' or '../'
a. LOAD_AS_FILE(Y + X) a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X) b. LOAD_AS_DIRECTORY(Y + X)
3. LOAD_NODE_MODULES(X, dirname(Y)) 3. LOAD_NODE_MODULES(X, dirname(Y))
@ -229,6 +240,7 @@ in pseudocode of what require.resolve does:
a. if PARTS[I] = "node_modules" CONTINUE a. if PARTS[I] = "node_modules" CONTINUE
c. DIR = path join(PARTS[0 .. I] + "node_modules") c. DIR = path join(PARTS[0 .. I] + "node_modules")
b. DIRS = DIRS + DIR b. DIRS = DIRS + DIR
c. let I = I - 1
6. return DIRS 6. return DIRS
### Loading from the `require.paths` Folders ### Loading from the `require.paths` Folders
@ -261,9 +273,7 @@ Global modules are lower priority than bundled dependencies.
#### **Note:** Please Avoid Modifying `require.paths` #### **Note:** Please Avoid Modifying `require.paths`
For compatibility reasons, `require.paths` is still given first priority `require.paths` may disappear in a future release.
in the module lookup process. However, it may disappear in a future
release.
While it seemed like a good idea at the time, and enabled a lot of While it seemed like a good idea at the time, and enabled a lot of
useful experimentation, in practice a mutable `require.paths` list is useful experimentation, in practice a mutable `require.paths` list is
@ -302,8 +312,23 @@ all modules.
As a result, if one node program comes to rely on this behavior, it may As a result, if one node program comes to rely on this behavior, it may
permanently and subtly alter the behavior of all other node programs in permanently and subtly alter the behavior of all other node programs in
the same process. As the application stack grows, we tend to assemble the same process. As the application stack grows, we tend to assemble
functionality, and it is a problem with those parts interact in ways functionality, and those parts interact in ways that are difficult to
that are difficult to predict. predict.
### Accessing the main module
When a file is run directly from Node, `require.main` is set to its
`module`. That means that you can determine whether a file has been run
directly by testing
require.main === module
For a file `foo.js`, this will be `true` if run via `node foo.js`, but
`false` if run by `require('./foo')`.
Because `module` provides a `filename` property (normally equivalent to
`__filename`), the entry point of the current application can be obtained
by checking `require.main.filename`.
## Addenda: Package Manager Tips ## Addenda: Package Manager Tips

16
doc/api/net.markdown

@ -106,6 +106,12 @@ Start a server listening for connections on the given file descriptor.
This file descriptor must have already had the `bind(2)` and `listen(2)` system This file descriptor must have already had the `bind(2)` and `listen(2)` system
calls invoked on it. calls invoked on it.
#### server.pause(msecs)
Stop accepting connections for the given number of milliseconds (default is
one second). This could be useful for throttling new connections against
DoS attacks or other oversubscription.
#### server.close() #### server.close()
Stops the server from accepting new connections. This function is Stops the server from accepting new connections. This function is
@ -115,8 +121,9 @@ event.
#### server.address() #### server.address()
Returns the bound address of the server as seen by the operating system. Returns the bound address and port of the server as reported by the operating system.
Useful to find which port was assigned when giving getting an OS-assigned address Useful to find which port was assigned when giving getting an OS-assigned address.
Returns an object with two properties, e.g. `{"address":"127.0.0.1", "port":2121}`
Example: Example:
@ -298,6 +305,11 @@ data packet received and the first keepalive probe. Setting 0 for
initialDelay will leave the value unchanged from the default initialDelay will leave the value unchanged from the default
(or previous) setting. (or previous) setting.
#### socket.address()
Returns the bound address and port of the socket as reported by the operating system.
Returns an object with two properties, e.g. `{"address":"192.168.57.1", "port":62053}`
#### socket.remoteAddress #### socket.remoteAddress
The string representation of the remote IP address. For example, The string representation of the remote IP address. For example,

4
doc/index.html

@ -215,6 +215,10 @@ server.listen(1337, "127.0.0.1");
<div style="clear: both; font-size: 8pt"> <div style="clear: both; font-size: 8pt">
Copyright 2010 Joyent, Inc Copyright 2010 Joyent, Inc
<br/>
Node.js is a trademark of Joyent, Inc.
See the <a href="trademark-policy.pdf">trademark policy</a>
for more information.
</div> </div>
<script type="text/javascript"> <script type="text/javascript">

BIN
doc/trademark-policy.pdf

Binary file not shown.

2
lib/dns.js

@ -247,7 +247,7 @@ var resolveMap = { A: exports.resolve4,
MX: exports.resolveMx, MX: exports.resolveMx,
TXT: exports.resolveTxt, TXT: exports.resolveTxt,
SRV: exports.resolveSrv, SRV: exports.resolveSrv,
PTR: exports.resolvePtr, PTR: exports.reverse,
NS: exports.resolveNs, NS: exports.resolveNs,
CNAME: exports.resolveCname }; CNAME: exports.resolveCname };

6
lib/events.js

@ -105,6 +105,9 @@ EventEmitter.prototype.addListener = function(type, listener) {
this._events[type] = listener; this._events[type] = listener;
} else if (isArray(this._events[type])) { } else if (isArray(this._events[type])) {
// If we've already got an array, just append.
this._events[type].push(listener);
// Check for listener leak // Check for listener leak
if (!this._events[type].warned) { if (!this._events[type].warned) {
var m; var m;
@ -123,9 +126,6 @@ EventEmitter.prototype.addListener = function(type, listener) {
console.trace(); console.trace();
} }
} }
// If we've already got an array, just append.
this._events[type].push(listener);
} else { } else {
// Adding the second element, need to change to array. // Adding the second element, need to change to array.
this._events[type] = [this._events[type], listener]; this._events[type] = [this._events[type], listener];

12
lib/http.js

@ -976,12 +976,20 @@ function connectionListener(socket) {
var self = this; var self = this;
var outgoing = []; var outgoing = [];
var incoming = []; var incoming = [];
var abortError = null;
function abortIncoming() { function abortIncoming() {
if (!abortError) {
abortError = new Error('http.ServerRequest was aborted by the client');
abortError.code = 'aborted';
}
while (incoming.length) { while (incoming.length) {
var req = incoming.shift(); var req = incoming.shift();
// @deprecated, should be removed in 0.5.x
req.emit('aborted'); req.emit('aborted');
req.emit('close'); req.emit('close', abortError);
} }
// abort socket._httpMessage ? // abort socket._httpMessage ?
} }
@ -992,6 +1000,8 @@ function connectionListener(socket) {
socket.setTimeout(2 * 60 * 1000); // 2 minute timeout socket.setTimeout(2 * 60 * 1000); // 2 minute timeout
socket.addListener('timeout', function() { socket.addListener('timeout', function() {
abortError = new Error('http.ServerRequest timed out');
abortError.code = 'timeout';
socket.destroy(); socket.destroy();
}); });

6
lib/tls.js

@ -925,10 +925,16 @@ function pipe(pair, socket) {
function onclose() { function onclose() {
socket.removeListener('error', onerror); socket.removeListener('error', onerror);
socket.removeListener('close', onclose); socket.removeListener('close', onclose);
socket.removeListener('timeout', ontimeout);
}
function ontimeout() {
cleartext.emit('timeout');
} }
socket.on('error', onerror); socket.on('error', onerror);
socket.on('close', onclose); socket.on('close', onclose);
socket.on('timeout', ontimeout);
return cleartext; return cleartext;
} }

45
lib/url.js

@ -42,6 +42,7 @@ var protocolPattern = /^([a-z0-9]+:)/i,
// them. // them.
nonHostChars = ['%', '/', '?', ';', '#'] nonHostChars = ['%', '/', '?', ';', '#']
.concat(unwise).concat(autoEscape), .concat(unwise).concat(autoEscape),
nonAuthChars = ['/', '@', '?', '#'].concat(delims),
hostnameMaxLen = 255, hostnameMaxLen = 255,
hostnamePartPattern = /^[a-zA-Z0-9][a-z0-9A-Z-]{0,62}$/, hostnamePartPattern = /^[a-zA-Z0-9][a-z0-9A-Z-]{0,62}$/,
hostnamePartStart = /^([a-zA-Z0-9][a-z0-9A-Z-]{0,62})(.*)$/, hostnamePartStart = /^([a-zA-Z0-9][a-z0-9A-Z-]{0,62})(.*)$/,
@ -123,12 +124,37 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
// there's a hostname. // there's a hostname.
// the first instance of /, ?, ;, or # ends the host. // the first instance of /, ?, ;, or # ends the host.
// don't enforce full RFC correctness, just be unstupid about it. // don't enforce full RFC correctness, just be unstupid about it.
// If there is an @ in the hostname, then non-host chars *are* allowed
// to the left of the first @ sign, unless some non-auth character
// comes *before* the @-sign.
// URLs are obnoxious.
var atSign = rest.indexOf('@');
if (atSign !== -1) {
// there *may be* an auth
var hasAuth = true;
for (var i = 0, l = nonAuthChars.length; i < l; i++) {
var index = rest.indexOf(nonAuthChars[i]);
if (index !== -1 && index < atSign) {
// not a valid auth. Something like http://foo.com/bar@baz/
hasAuth = false;
break;
}
}
if (hasAuth) {
// pluck off the auth portion.
out.auth = rest.substr(0, atSign);
rest = rest.substr(atSign + 1);
}
}
var firstNonHost = -1; var firstNonHost = -1;
for (var i = 0, l = nonHostChars.length; i < l; i++) { for (var i = 0, l = nonHostChars.length; i < l; i++) {
var index = rest.indexOf(nonHostChars[i]); var index = rest.indexOf(nonHostChars[i]);
if (index !== -1 && if (index !== -1 &&
(firstNonHost < 0 || index < firstNonHost)) firstNonHost = index; (firstNonHost < 0 || index < firstNonHost)) firstNonHost = index;
} }
if (firstNonHost !== -1) { if (firstNonHost !== -1) {
out.host = rest.substr(0, firstNonHost); out.host = rest.substr(0, firstNonHost);
rest = rest.substr(firstNonHost); rest = rest.substr(firstNonHost);
@ -137,8 +163,9 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
rest = ''; rest = '';
} }
// pull out the auth and port. // pull out port.
var p = parseHost(out.host); var p = parseHost(out.host);
if (out.auth) out.host = out.auth + '@' + out.host;
var keys = Object.keys(p); var keys = Object.keys(p);
for (var i = 0, l = keys.length; i < l; i++) { for (var i = 0, l = keys.length; i < l; i++) {
var key = keys[i]; var key = keys[i];
@ -250,10 +277,19 @@ function urlFormat(obj) {
// to clean up potentially wonky urls. // to clean up potentially wonky urls.
if (typeof(obj) === 'string') obj = urlParse(obj); if (typeof(obj) === 'string') obj = urlParse(obj);
var auth = obj.auth;
if (auth) {
auth = auth.split('@').join('%40');
for (var i = 0, l = nonAuthChars.length; i < l; i++) {
var nAC = nonAuthChars[i];
auth = auth.split(nAC).join(encodeURIComponent(nAC));
}
}
var protocol = obj.protocol || '', var protocol = obj.protocol || '',
host = (obj.host !== undefined) ? obj.host : host = (obj.host !== undefined) ? obj.host :
obj.hostname !== undefined ? ( obj.hostname !== undefined ? (
(obj.auth ? obj.auth + '@' : '') + (auth ? auth + '@' : '') +
obj.hostname + obj.hostname +
(obj.port ? ':' + obj.port : '') (obj.port ? ':' + obj.port : '')
) : ) :
@ -476,11 +512,6 @@ function urlResolveObject(source, relative) {
function parseHost(host) { function parseHost(host) {
var out = {}; var out = {};
var at = host.indexOf('@');
if (at !== -1) {
out.auth = host.substr(0, at);
host = host.substr(at + 1); // drop the @
}
var port = portPattern.exec(host); var port = portPattern.exec(host);
if (port) { if (port) {
port = port[0]; port = port[0];

1
src/node.cc

@ -1209,7 +1209,6 @@ ssize_t DecodeWrite(char *buf,
for (size_t i = 0; i < buflen; i++) { for (size_t i = 0; i < buflen; i++) {
unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]); unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]);
assert(b[1] == 0);
buf[i] = b[0]; buf[i] = b[0];
} }

13
src/node_crypto.cc

@ -3566,7 +3566,6 @@ class DiffieHellman : public ObjectWrap {
}; };
void InitCrypto(Handle<Object> target) { void InitCrypto(Handle<Object> target) {
HandleScope scope; HandleScope scope;
@ -3576,6 +3575,18 @@ void InitCrypto(Handle<Object> target) {
SSL_load_error_strings(); SSL_load_error_strings();
ERR_load_crypto_strings(); ERR_load_crypto_strings();
// Turn off compression. Saves memory - do it in userland.
STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_methods();
#if 0
if (comp_methods && sk_SSL_COMP_num(comp_methods) > 0) {
default_compression_method = sk_SSL_COMP_pop(comp_methods);
fprintf(stderr, "SSL_COMP_get_name %s\n",
SSL_COMP_get_name(default_compression_method->method));
}
#endif
sk_SSL_COMP_zero(comp_methods);
assert(sk_SSL_COMP_num(comp_methods) == 0);
SecureContext::Initialize(target); SecureContext::Initialize(target);
Connection::Initialize(target); Connection::Initialize(target);
Cipher::Initialize(target); Cipher::Initialize(target);

15
test/simple/test-buffer.js

@ -562,3 +562,18 @@ for (; i < b.length; i++) assert.equal(0, b[i]);
var b = new SlowBuffer(10); var b = new SlowBuffer(10);
b.write('あいうえお', 'ucs2'); b.write('あいうえお', 'ucs2');
assert.equal(b.toString('ucs2'), 'あいうえお'); assert.equal(b.toString('ucs2'), 'あいうえお');
// Binary encoding should write only one byte per character.
var b = Buffer([0xde, 0xad, 0xbe, 0xef]);
var s = String.fromCharCode(0xffff);
b.write(s, 0, 'binary')
assert.equal(0xff, b[0]);
assert.equal(0xad, b[1]);
assert.equal(0xbe, b[2]);
assert.equal(0xef, b[3]);
s = String.fromCharCode(0xaaee);
b.write(s, 0, 'binary')
assert.equal(0xee, b[0]);
assert.equal(0xad, b[1]);
assert.equal(0xbe, b[2]);
assert.equal(0xef, b[3]);

6
test/simple/test-c-ares.js

@ -58,3 +58,9 @@ dns.lookup('ipv6.google.com', function(error, result, addressType) {
//assert.equal('string', typeof result); //assert.equal('string', typeof result);
assert.equal(6, addressType); assert.equal(6, addressType);
}); });
dns.resolve('127.0.0.1', 'PTR', function(error, domains) {
if (error) throw error;
assert.ok(Array.isArray(domains));
});

29
test/simple/test-event-emitter-check-listener-leaks.js

@ -0,0 +1,29 @@
var assert = require('assert');
var events = require('events');
var e = new events.EventEmitter();
// default
for (var i = 0; i < 10; i++) {
e.on('default', function() {});
}
assert.ok(!e._events['default'].hasOwnProperty('warned'));
e.on('default', function() {});
assert.ok(e._events['default'].warned);
// specific
e.setMaxListeners(5);
for (var i = 0; i < 5; i++) {
e.on('specific', function() {});
}
assert.ok(!e._events['specific'].hasOwnProperty('warned'));
e.on('specific', function() {});
assert.ok(e._events['specific'].warned);
// unlimited
e.setMaxListeners(0);
for (var i = 0; i < 1000; i++) {
e.on('unlimited', function() {});
}
assert.ok(!e._events['unlimited'].hasOwnProperty('warned'));

44
test/simple/test-http-request-aborted.js

@ -0,0 +1,44 @@
// 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 closeError;
var server = http.Server(function(req, res) {
req.on('close', function(err) {
closeError = err;
server.close();
});
});
server.listen(common.PORT, function() {
var socket = net.createConnection(common.PORT);
socket.write('GET / HTTP/1.1\n\n');
socket.end();
});
process.on('exit', function() {
assert.equal(closeError.code, 'aborted');
});

9
test/simple/test-http-set-timeout.js

@ -24,11 +24,12 @@ var assert = require('assert');
var http = require('http'); var http = require('http');
var server = http.createServer(function(req, res) { var server = http.createServer(function(req, res) {
console.log('got request. setting 1 second timeout'); console.log('got request. setting 100ms second timeout');
req.connection.setTimeout(500); req.connection.setTimeout(100);
req.on('close', function(err) {
assert.strictEqual(err.code, 'timeout');
req.connection.addListener('timeout', function() {
req.connection.destroy();
common.debug('TIMEOUT'); common.debug('TIMEOUT');
server.close(); server.close();
}); });

53
test/simple/test-https-request-aborted.js

@ -0,0 +1,53 @@
// 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 https = require('https');
var fs = require('fs');
var closeError;
var options = {
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
};
var server = https.Server(options, function(req, res) {
res.writeHead(200);
res.write('Hi');
req.on('close', function(err) {
closeError = err;
server.close();
});
});
server.listen(common.PORT, function() {
https.get({port: common.PORT, path: '/'}, function(res) {
res.socket.end();
})
});
process.on('exit', function() {
console.log(closeError);
assert.equal(closeError.code, 'aborted');
});

53
test/simple/test-https-request-timeout.js

@ -0,0 +1,53 @@
// 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 https = require('https');
var fs = require('fs');
var closeError;
var options = {
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
};
var server = https.Server(options, function(req, res) {
req.connection.setTimeout(100);
res.writeHead(200);
res.write('Hi');
req.on('close', function(err) {
closeError = err;
server.close();
});
});
server.listen(common.PORT, function() {
https.get({port: common.PORT, path: '/'}, function(res) {
})
});
process.on('exit', function() {
assert.equal(closeError.code, 'timeout');
});

50
test/simple/test-tls-request-timeout.js

@ -0,0 +1,50 @@
// 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 tls = require('tls');
var fs = require('fs');
var hadTimeout = false;
var options = {
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
};
var server = tls.Server(options, function(socket) {
socket.setTimeout(100);
socket.on('timeout', function(err) {
hadTimeout = true;
socket.end();
server.close();
});
});
server.listen(common.PORT, function() {
var socket = tls.connect(common.PORT);
});
process.on('exit', function() {
assert.ok(hadTimeout);
});

26
test/simple/test-url.js

@ -236,6 +236,18 @@ var parseTests = {
'host': 'isaacschlueter@jabber.org', 'host': 'isaacschlueter@jabber.org',
'auth': 'isaacschlueter', 'auth': 'isaacschlueter',
'hostname': 'jabber.org' 'hostname': 'jabber.org'
},
'http://atpass:foo%40bar@127.0.0.1:8080/path?search=foo#bar' : {
'href' : 'http://atpass:foo%40bar@127.0.0.1:8080/path?search=foo#bar',
'protocol' : 'http:',
'host' : 'atpass:foo%40bar@127.0.0.1:8080',
'auth' : 'atpass:foo%40bar',
'hostname' : '127.0.0.1',
'port' : '8080',
'pathname': '/path',
'search' : '?search=foo',
'query' : 'search=foo',
'hash' : '#bar'
} }
}; };
for (var u in parseTests) { for (var u in parseTests) {
@ -367,6 +379,20 @@ var formatTests = {
'host': 'isaacschlueter@jabber.org', 'host': 'isaacschlueter@jabber.org',
'auth': 'isaacschlueter', 'auth': 'isaacschlueter',
'hostname': 'jabber.org' 'hostname': 'jabber.org'
},
'http://atpass:foo%40bar@127.0.0.1/' : {
'href': 'http://atpass:foo%40bar@127.0.0.1/',
'auth': 'atpass:foo@bar',
'hostname': '127.0.0.1',
'protocol': 'http:',
'pathname': '/'
},
'http://atslash%2F%40:%2F%40@foo/' : {
'href': 'http://atslash%2F%40:%2F%40@foo/',
'auth': 'atslash/@:/@',
'hostname': 'foo',
'protocol': 'http:',
'pathname': '/'
} }
}; };
for (var u in formatTests) { for (var u in formatTests) {

Loading…
Cancel
Save