Skip to content

Commit 04d9aae

Browse files
committed
Node.js document loader updates.
- Add 'httpAgent' and 'httpsAgent' options. - Default 'user-agent' header to 'jsonld.js'. - Fix document loader tests and enable by default. - Add local test server. - Fix old tests. - Add more coverage.
1 parent d12b4e3 commit 04d9aae

File tree

5 files changed

+461
-73
lines changed

5 files changed

+461
-73
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
versions.
2020
- Use Babel `usage` mode rather than listing individual polyfills. May increase
2121
bundle size due to more accurate support of intended output targets.
22+
- Default Node.js document loader `user-agent` header set to "jsonld.js".
2223

2324
### Added
2425
- Distribute a `jsonld.esm.min.js` bundle optimized for the features available
2526
in browsers that support ES Modules.
27+
- Default Node.js document loader `httpAgent` and `httpsAgent` options.
2628

2729
### Removed
2830
- Use of deprecated library `request` in Node.js documentLoader.

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,12 @@ const compacted = await jsonld.compact(
340340
doc, context, {documentLoader: customLoader});
341341
```
342342

343+
### Node.js Document Loader User-Agent
344+
345+
It is recommended to set a default `user-agent` header for Node.js
346+
applications. The default for the default Node.js document loader is
347+
`jsonld.js`.
348+
343349
Related Modules
344350
---------------
345351

lib/documentLoaders/node.js

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,35 @@ const {httpClient} = require('@digitalbazaar/http-client');
1515
* Creates a built-in node document loader.
1616
*
1717
* @param options the options to use:
18-
* secure: require all URLs to use HTTPS.
19-
* strictSSL: true to require SSL certificates to be valid,
20-
* false not to (default: true).
21-
* maxRedirects: the maximum number of redirects to permit, none by
22-
* default.
23-
* headers: an object (map) of headers which will be passed as request
24-
* headers for the requested document. Accept is not allowed.
18+
* [secure]: require all URLs to use HTTPS. (default: false)
19+
* [strictSSL]: true to require SSL certificates to be valid,
20+
* false not to. (default: true)
21+
* [maxRedirects]: the maximum number of redirects to permit.
22+
* (default: none)
23+
* [headers]: an object (map) of headers which will be passed as
24+
* request headers for the requested document. Accept is not
25+
* allowed. (default: none).
26+
* [httpAgent]: a Node.js `http.Agent` to use with 'http' requests.
27+
* (default: none)
28+
* [httpsAgent]: a Node.js `https.Agent` to use with 'https' requests.
29+
* (default: An agent with rejectUnauthorized to the strictSSL
30+
* value)
2531
*
2632
* @return the node document loader.
2733
*/
2834
module.exports = ({
2935
secure,
3036
strictSSL = true,
3137
maxRedirects = -1,
32-
headers = {}
38+
headers = {},
39+
httpAgent,
40+
httpsAgent
3341
} = {strictSSL: true, maxRedirects: -1, headers: {}}) => {
3442
headers = buildHeaders(headers);
43+
// set a default header if none was set
44+
if(!('user-agent' in headers)) {
45+
headers['user-agent'] = 'jsonld.js';
46+
}
3547
const http = require('http');
3648

3749
const queue = new RequestQueue();
@@ -40,13 +52,15 @@ module.exports = ({
4052
});
4153

4254
async function loadDocument(url, redirects) {
43-
if(url.indexOf('http:') !== 0 && url.indexOf('https:') !== 0) {
55+
const isHttp = url.startsWith('http:');
56+
const isHttps = url.startsWith('https:');
57+
if(!isHttp && !isHttps) {
4458
throw new JsonLdError(
4559
'URL could not be dereferenced; only "http" and "https" URLs are ' +
4660
'supported.',
4761
'jsonld.InvalidUrl', {code: 'loading document failed', url});
4862
}
49-
if(secure && url.indexOf('https') !== 0) {
63+
if(secure && !isHttps) {
5064
throw new JsonLdError(
5165
'URL could not be dereferenced; secure mode is enabled and ' +
5266
'the URL\'s scheme is not "https".',
@@ -60,7 +74,9 @@ module.exports = ({
6074

6175
let alternate = null;
6276

63-
const {res, body} = await _fetch({url, headers, strictSSL});
77+
const {res, body} = await _fetch({
78+
url, headers, strictSSL, httpAgent, httpsAgent
79+
});
6480
doc = {contextUrl: null, documentUrl: url, document: body || null};
6581
// handle error
6682
const statusText = http.STATUS_CODES[res.status];
@@ -143,11 +159,19 @@ module.exports = ({
143159
}
144160
};
145161

146-
async function _fetch({url, headers, strictSSL}) {
162+
async function _fetch({url, headers, strictSSL, httpAgent, httpsAgent}) {
147163
try {
148-
const agent = new https.Agent({rejectUnauthorized: strictSSL});
149-
const res = await httpClient.get(
150-
url, {headers, agent, redirect: 'manual'});
164+
const options = {headers, redirect: 'manual'};
165+
const isHttps = url.startsWith('https:');
166+
if(isHttps) {
167+
options.agent =
168+
httpsAgent || new https.Agent({rejectUnauthorized: strictSSL});
169+
} else {
170+
if(httpAgent) {
171+
options.agent = httpAgent;
172+
}
173+
}
174+
const res = await httpClient.get(url, options);
151175
const body = JSON.stringify(res.data, null, 2);
152176
return {res, body};
153177
} catch(e) {

0 commit comments

Comments
 (0)