Allow Node.js to work with https (#2667)

Detect the protocol and pick the right module as needed.

Fixes #2613
This commit is contained in:
Erik Arvidsson
2016-10-03 18:28:11 -07:00
committed by GitHub
parent 4a562d81ef
commit cdba35e70a
3 changed files with 54 additions and 3 deletions

View File

@@ -38,6 +38,7 @@
"flow-bin": "^0.32.0",
"fs-extra": "^0.30.0",
"mocha": "^2.5.3",
"mock-require": "^1.3.0",
"nyc": "^8.3.0"
},
"scripts": {

44
js/noms/src/fetch-test.js Normal file
View File

@@ -0,0 +1,44 @@
// @flow
// Copyright 2016 Attic Labs, Inc. All rights reserved.
// Licensed under the Apache License, version 2.0:
// http://www.apache.org/licenses/LICENSE-2.0
import {assert} from 'chai';
import {suite, test, setup, teardown} from 'mocha';
import mock from 'mock-require';
suite('fetch', () => {
let log;
setup(() => {
log = [];
for (const protocol of ['http', 'https']) {
mock(protocol, {
request(options) {
log.push(protocol, options.href);
return {
end() {},
on() {},
setTimeout() {},
};
},
});
}
});
teardown(() => {
mock.stopAll();
});
test('http vs https', () => {
const {fetchText} = mock.reRequire('./fetch.js');
fetchText('http://example.com');
assert.deepEqual(log, ['http', 'http://example.com/']);
log = [];
fetchText('https://example.com');
assert.deepEqual(log, ['https', 'https://example.com/']);
});
});

View File

@@ -4,7 +4,8 @@
// Licensed under the Apache License, version 2.0:
// http://www.apache.org/licenses/LICENSE-2.0
import {request} from 'http';
import * as http from 'http';
import * as https from 'https';
import {parse} from 'url';
import * as Bytes from './bytes.js';
@@ -27,6 +28,11 @@ function objectToMap<T>(object: {[key: string]: T}): Map<string, T> {
return m;
}
const requestModules = {
'http:': http,
'https:': https,
};
function fetch(url: string, options: FetchOptions = {}): Promise<BufResponse> {
const opts: any = parse(url);
opts.method = options.method || 'GET';
@@ -34,7 +40,7 @@ function fetch(url: string, options: FetchOptions = {}): Promise<BufResponse> {
opts.headers = options.headers;
}
return new Promise((resolve, reject) => {
const req = request(opts, res => {
const req = requestModules[opts.protocol].request(opts, res => {
if (res.statusCode < 200 || res.statusCode >= 300) {
reject(new Error(`HTTP Error: ${res.statusCode}`));
return;
@@ -72,7 +78,7 @@ function fetch(url: string, options: FetchOptions = {}): Promise<BufResponse> {
// then catch that event and report an error.
req.setTimeout(2 * 60 * 1000, () => req.abort());
req.on('abort', () => {
reject(new Error('HTTP request timed out'));
reject(new Error('Request timed out'));
});
if (options.body) {