Skip to content

Commit

Permalink
http: allow createServer() to return a HTTPS server
Browse files Browse the repository at this point in the history
This commit allows the http module to create a HTTPS server
if TLS options are passed to createServer() or the Server()
constructor.
  • Loading branch information
cjihrig authored and brendanashworth committed Mar 8, 2015
1 parent fe36076 commit 8ff6b81
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 6 deletions.
6 changes: 4 additions & 2 deletions doc/api/http.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ A collection of all the standard HTTP response status codes, and the
short description of each. For example, `http.STATUS_CODES[404] === 'Not
Found'`.

## http.createServer([requestListener])
## http.createServer([options][, requestListener])

Returns a new instance of [http.Server](#http_class_http_server).
Returns a new instance of [http.Server](#http_class_http_server). If an `options` object containing valid TLS
arguments is passed, then a HTTPS server will be returned based on the
options.

The `requestListener` is a function which is automatically
added to the `'request'` event.
Expand Down
21 changes: 19 additions & 2 deletions lib/_http_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,25 @@ ServerResponse.prototype.writeHeader = function() {
};


function Server(requestListener) {
if (!(this instanceof Server)) return new Server(requestListener);
var TLS_ARGS = ['pfx', 'key', 'passphrase', 'cert', 'ca', 'crl', 'ciphers',
'handshakeTimeout', 'honorCipherOrder', 'requestCert',
'rejectUnauthorized', 'NPNProtocols', 'SNICallback',
'sessionIdContext', 'secureProtocol', 'secureOptions'];

function Server(options, requestListener) {
if (util.isObject(options)) {
// Only return an HTTPS server if valid TLS args are passed
for (var i = 0; i < TLS_ARGS.length; i++) {
if (options.hasOwnProperty(TLS_ARGS[i]))
return new require('https').Server(options, requestListener);
}
} else {
requestListener = options;
}

if (!(this instanceof Server))
return new Server(requestListener);

net.Server.call(this, { allowHalfOpen: true });

if (requestListener) {
Expand Down
4 changes: 2 additions & 2 deletions lib/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ exports.get = function(options, cb) {
exports._connectionListener = server._connectionListener;
const Server = exports.Server = server.Server;

exports.createServer = function(requestListener) {
return new Server(requestListener);
exports.createServer = function(options, requestListener) {
return new Server(options, requestListener);
};


Expand Down
4 changes: 4 additions & 0 deletions test/parallel/test-http-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ var server = http.createServer(function(req, res) {
}, 1);

});
assert(server instanceof http.Server);
server.listen(common.PORT);

server.httpAllowHalfOpen = true;
Expand Down Expand Up @@ -93,6 +94,9 @@ server.on('listening', function() {
});
});

assert(http.createServer() instanceof http.Server);
assert(http.createServer({foo: 1}) instanceof http.Server);

process.on('exit', function() {
assert.equal(4, request_number);
assert.equal(4, requests_sent);
Expand Down
69 changes: 69 additions & 0 deletions test/simple/test-https-from-http.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// 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.

if (!process.versions.openssl) {
console.error('Skipping because node compiled without OpenSSL.');
process.exit(0);
}

var common = require('../common');
var assert = require('assert');
var fs = require('fs');
var http = require('http');
var https = require('https');

var options = {
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
};

var reqCount = 0;
var body = 'test';

var server = http.createServer(options, function(req, res) {
reqCount++;
res.writeHead(200, {'content-type': 'text/plain'});
res.end(body);
});

assert(server instanceof https.Server);

server.listen(common.PORT, function() {
https.get({
port: common.PORT,
rejectUnauthorized: false
}, function(res) {
var data = '';

res.on('data', function(chunk) {
data += chunk.toString();
});

res.on('end', function() {
assert.equal(data, body);
server.close();
});
});
});

process.on('exit', function() {
assert.equal(1, reqCount);
});

0 comments on commit 8ff6b81

Please sign in to comment.