Skip to content

Commit 8ff6b81

Browse files
cjihrigbrendanashworth
authored andcommitted
http: allow createServer() to return a HTTPS server
This commit allows the http module to create a HTTPS server if TLS options are passed to createServer() or the Server() constructor.
1 parent fe36076 commit 8ff6b81

5 files changed

Lines changed: 98 additions & 6 deletions

File tree

doc/api/http.markdown

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ A collection of all the standard HTTP response status codes, and the
5757
short description of each. For example, `http.STATUS_CODES[404] === 'Not
5858
Found'`.
5959

60-
## http.createServer([requestListener])
60+
## http.createServer([options][, requestListener])
6161

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

6466
The `requestListener` is a function which is automatically
6567
added to the `'request'` event.

lib/_http_server.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,25 @@ ServerResponse.prototype.writeHeader = function() {
213213
};
214214

215215

216-
function Server(requestListener) {
217-
if (!(this instanceof Server)) return new Server(requestListener);
216+
var TLS_ARGS = ['pfx', 'key', 'passphrase', 'cert', 'ca', 'crl', 'ciphers',
217+
'handshakeTimeout', 'honorCipherOrder', 'requestCert',
218+
'rejectUnauthorized', 'NPNProtocols', 'SNICallback',
219+
'sessionIdContext', 'secureProtocol', 'secureOptions'];
220+
221+
function Server(options, requestListener) {
222+
if (util.isObject(options)) {
223+
// Only return an HTTPS server if valid TLS args are passed
224+
for (var i = 0; i < TLS_ARGS.length; i++) {
225+
if (options.hasOwnProperty(TLS_ARGS[i]))
226+
return new require('https').Server(options, requestListener);
227+
}
228+
} else {
229+
requestListener = options;
230+
}
231+
232+
if (!(this instanceof Server))
233+
return new Server(requestListener);
234+
218235
net.Server.call(this, { allowHalfOpen: true });
219236

220237
if (requestListener) {

lib/http.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ exports.get = function(options, cb) {
3939
exports._connectionListener = server._connectionListener;
4040
const Server = exports.Server = server.Server;
4141

42-
exports.createServer = function(requestListener) {
43-
return new Server(requestListener);
42+
exports.createServer = function(options, requestListener) {
43+
return new Server(options, requestListener);
4444
};
4545

4646

test/parallel/test-http-server.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ var server = http.createServer(function(req, res) {
4646
}, 1);
4747

4848
});
49+
assert(server instanceof http.Server);
4950
server.listen(common.PORT);
5051

5152
server.httpAllowHalfOpen = true;
@@ -93,6 +94,9 @@ server.on('listening', function() {
9394
});
9495
});
9596

97+
assert(http.createServer() instanceof http.Server);
98+
assert(http.createServer({foo: 1}) instanceof http.Server);
99+
96100
process.on('exit', function() {
97101
assert.equal(4, request_number);
98102
assert.equal(4, requests_sent);
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
if (!process.versions.openssl) {
23+
console.error('Skipping because node compiled without OpenSSL.');
24+
process.exit(0);
25+
}
26+
27+
var common = require('../common');
28+
var assert = require('assert');
29+
var fs = require('fs');
30+
var http = require('http');
31+
var https = require('https');
32+
33+
var options = {
34+
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
35+
cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
36+
};
37+
38+
var reqCount = 0;
39+
var body = 'test';
40+
41+
var server = http.createServer(options, function(req, res) {
42+
reqCount++;
43+
res.writeHead(200, {'content-type': 'text/plain'});
44+
res.end(body);
45+
});
46+
47+
assert(server instanceof https.Server);
48+
49+
server.listen(common.PORT, function() {
50+
https.get({
51+
port: common.PORT,
52+
rejectUnauthorized: false
53+
}, function(res) {
54+
var data = '';
55+
56+
res.on('data', function(chunk) {
57+
data += chunk.toString();
58+
});
59+
60+
res.on('end', function() {
61+
assert.equal(data, body);
62+
server.close();
63+
});
64+
});
65+
});
66+
67+
process.on('exit', function() {
68+
assert.equal(1, reqCount);
69+
});

0 commit comments

Comments
 (0)