Merge branch 'v0.4'
authorRyan Dahl <ry@tinyclouds.org>
Fri, 20 May 2011 17:27:39 +0000 (10:27 -0700)
committerRyan Dahl <ry@tinyclouds.org>
Fri, 20 May 2011 17:29:16 +0000 (10:29 -0700)
Conflicts:
lib/crypto.js
lib/tls.js

1  2 
doc/api/http.markdown
lib/crypto.js
lib/tls.js
src/node_buffer.cc
src/platform_sunos.cc
test/simple/test-buffer.js
test/simple/test-http-upgrade-agent.js

@@@ -475,21 -474,61 +475,67 @@@ an HTTP server. Normally `Agent` instan
  code, however in certain situations it's useful to check the status of the
  agent. The `http.getAgent()` function allows you to access the agents.
  
 +Options:
 +
 +- `host`: A domain name or IP address of the server to issue the request to.
 +- `port`: Port of remote server.
 +- `socketPath`: Unix Domain Socket (use one of host:port or socketPath)
 +
  ### Event: 'upgrade'
  
- `function (request, socket, head)`
+ `function (response, socket, head)`
+ Emitted each time a server responds to a request with an upgrade. If this
+ event isn't being listened for, clients receiving an upgrade header will have
+ their connections closed.
+ A client server pair that show you how to listen for the `upgrade` event using `http.getAgent`:
  
- Emitted each time a server responds to a request with an upgrade. If this event
- isn't being listened for, clients receiving an upgrade header will have their
- connections closed.
+     var http = require('http');
+     var net = require('net');
+     // Create an HTTP server
+     var srv = http.createServer(function (req, res) {
+       res.writeHead(200, {'Content-Type': 'text/plain'});
+       res.end('okay');
+     });
+     srv.on('upgrade', function(req, socket, upgradeHead) {
+       socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
+                    'Upgrade: WebSocket\r\n' +
+                    'Connection: Upgrade\r\n' +
+                    '\r\n\r\n');
+       socket.ondata = function(data, start, end) {
+         socket.write(data.toString('utf8', start, end), 'utf8'); // echo back
+       };
+     });
+     // now that server is running
+     srv.listen(1337, '127.0.0.1', function() {
+       // make a request
+       var agent = http.getAgent('127.0.0.1', 1337);
+       var options = {
+         agent: agent,
+         port: 1337,
+         host: '127.0.0.1',
+         headers: {
+           'Connection': 'Upgrade',
+           'Upgrade': 'websocket'
+         }
+       };
+       var req = http.request(options);
+       req.end();
+       agent.on('upgrade', function(res, socket, upgradeHead) {
+         console.log('got upgraded!');
+         socket.end();
+         process.exit(0);
+       });
+     });
  
- See the description of the [upgrade event](http.html#event_upgrade_) for `http.Server` for further details.
  
  ### Event: 'continue'
  
diff --cc lib/crypto.js
@@@ -37,7 -36,7 +37,7 @@@ try 
  }
  
  
- function Credentials(secureProtocol, flags) {
 -function Credentials(secureProtocol, context) {
++function Credentials(secureProtocol, flags, context) {
    if (!(this instanceof Credentials)) {
      return new Credentials(secureProtocol);
    }
      throw new Error('node.js not compiled with openssl crypto support.');
    }
  
-   this.context = new SecureContext();
-   if (secureProtocol) {
-     this.context.init(secureProtocol);
+   if (context) {
+     this.context = context;
    } else {
-     this.context.init();
-   }
+     this.context = new SecureContext();
  
-   if(flags) this.context.setOptions(flags);
+     if (secureProtocol) {
+       this.context.init(secureProtocol);
+     } else {
+       this.context.init();
+     }
+   }
 +
++  if (flags) this.context.setOptions(flags);
  }
  
  exports.Credentials = Credentials;
  
  
- exports.createCredentials = function(options) {
+ exports.createCredentials = function(options, context) {
    if (!options) options = {};
-   var c = new Credentials(options.secureProtocol, options.secureOptions);
 -  var c = new Credentials(options.secureProtocol, context);
++
++  var c = new Credentials(options.secureProtocol,
++                          options.secureOptions,
++                          context);
+   if (context) return c;
  
    if (options.key) c.context.setKey(options.key);
  
diff --cc lib/tls.js
@@@ -750,18 -727,23 +764,24 @@@ function Server(/* [options], listener 
  
    var self = this;
  
+   // Handle option defaults:
+   this.setOptions(options);
+   var sharedCreds = crypto.createCredentials({
+     key: self.key,
+     cert: self.cert,
+     ca: self.ca,
+     ciphers: self.ciphers,
+     secureProtocol: self.secureProtocol,
++    secureOptions: self.secureOptions,
+     crl: self.crl
+   });
+   sharedCreds.context.setCiphers('RC4-SHA:AES128-SHA:AES256-SHA');
    // constructor call
    net.Server.call(this, function(socket) {
-     var creds = crypto.createCredentials({
-       key: self.key,
-       cert: self.cert,
-       ca: self.ca,
-       ciphers: self.ciphers,
-       secureProtocol: self.secureProtocol,
-       secureOptions: self.secureOptions,
-       crl: self.crl
-     });
-     creds.context.setCiphers('RC4-SHA:AES128-SHA:AES256-SHA');
+     var creds = crypto.createCredentials(null, sharedCreds.context);
  
      var pair = new SecurePair(creds,
                                true,
Simple merge
@@@ -229,10 -243,13 +251,13 @@@ double Platform::GetFreeMemory() 
  
  
  double Platform::GetTotalMemory() {
-   return 0.0;
+   double pagesize = static_cast<double>(sysconf(_SC_PAGESIZE));
+   double pages = static_cast<double>(sysconf(_SC_PHYS_PAGES));
+   return pagesize*pages;
  }
  
 -double Platform::GetUptime() {
 +double Platform::GetUptimeImpl() {
    kstat_ctl_t   *kc;
    kstat_t       *ksp;
    kstat_named_t *knp;
Simple merge
index 0000000,fd8c626..9f80590
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,90 +1,93 @@@
 -  var agent = http.getAgent('127.0.0.1', common.PORT);
+ // 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.
+ // Verify that the 'upgrade' header causes an 'upgrade' event to be emitted to
+ // the HTTP client. This test uses a raw TCP server to better control server
+ // behavior.
+ var common = require('../common');
+ var assert = require('assert');
+ var http = require('http');
+ var net = require('net');
+ // Create a TCP server
+ var srv = net.createServer(function(c) {
+   var data = '';
+   c.addListener('data', function(d) {
+     data += d.toString('utf8');
+     c.write('HTTP/1.1 101\r\n');
+     c.write('hello: world\r\n');
+     c.write('connection: upgrade\r\n');
+     c.write('upgrade: websocket\r\n');
+     c.write('\r\n');
+     c.write('nurtzo');
+   });
+   c.addListener('end', function() {
+     c.end();
+   });
+ });
+ var gotUpgrade = false;
+ srv.listen(common.PORT, '127.0.0.1', function() {
++  var agent = http.getAgent({
++    host: '127.0.0.1',
++    port: common.PORT
++  });
+   assert.ok(agent);
+   var options = {
+     port: common.PORT,
+     host: '127.0.0.1',
+     headers: {
+       'upgrade': 'websocket'
+     }
+   };
+   var req = http.request(options);
+   req.end();
+   agent.on('upgrade', function(res, socket, upgradeHead) {
+     // XXX: This test isn't fantastic, as it assumes that the entire response
+     //      from the server will arrive in a single data callback
+     assert.equal(upgradeHead, 'nurtzo');
+     console.log(res.headers);
+     var expectedHeaders = { 'hello': 'world',
+                             'connection': 'upgrade',
+                             'upgrade': 'websocket' };
+     assert.deepEqual(expectedHeaders, res.headers);
+     socket.end();
+     srv.close();
+     gotUpgrade = true;
+   });
+ });
+ process.addListener('exit', function() {
+   assert.ok(gotUpgrade);
+ });