@loopback/http-caching-proxy
Advanced tools
Comparing version 1.3.0 to 2.0.0
@@ -6,2 +6,33 @@ # Change Log | ||
# [2.0.0](https://github.com/strongloop/loopback-next/compare/@loopback/http-caching-proxy@1.3.0...@loopback/http-caching-proxy@2.0.0) (2020-03-05) | ||
### Bug Fixes | ||
* extend test timeout for windows ([249198e](https://github.com/strongloop/loopback-next/commit/249198e41d6ad567f1582701c25abf29fc08c809)), closes [#4425](https://github.com/strongloop/loopback-next/issues/4425) | ||
### chore | ||
* remove support for Node.js v8.x ([4281d9d](https://github.com/strongloop/loopback-next/commit/4281d9df50f0715d32879e1442a90b643ec8f542)) | ||
### Features | ||
* add `tslib` as dependency ([a6e0b4c](https://github.com/strongloop/loopback-next/commit/a6e0b4ce7b862764167cefedee14c1115b25e0a4)), closes [#4676](https://github.com/strongloop/loopback-next/issues/4676) | ||
* **http-caching-proxy:** replace usage of request with axios as http client ([cd89ad4](https://github.com/strongloop/loopback-next/commit/cd89ad4cb979931b265af24de316e11262084090)) | ||
### BREAKING CHANGES | ||
* **http-caching-proxy:** [axios](https://github.com/axios/) is now used as the | ||
http client package to replace [request](https://github.com/request/request) | ||
which is now deprecated. | ||
* Node.js v8.x is now end of life. Please upgrade to version | ||
10 and above. See https://nodejs.org/en/about/releases. | ||
# [1.3.0](https://github.com/strongloop/loopback-next/compare/@loopback/http-caching-proxy@1.2.5...@loopback/http-caching-proxy@1.3.0) (2020-02-05) | ||
@@ -8,0 +39,0 @@ |
@@ -33,2 +33,3 @@ /// <reference types="node" /> | ||
export declare class HttpCachingProxy { | ||
private _axios; | ||
private _options; | ||
@@ -35,0 +36,0 @@ private _server?; |
@@ -6,10 +6,8 @@ "use strict"; | ||
// License text available at https://opensource.org/licenses/MIT | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const debug_1 = __importDefault(require("debug")); | ||
const tslib_1 = require("tslib"); | ||
const axios_1 = tslib_1.__importDefault(require("axios")); | ||
const debug_1 = tslib_1.__importDefault(require("debug")); | ||
const http_1 = require("http"); | ||
const p_event_1 = __importDefault(require("p-event")); | ||
const request_promise_native_1 = __importDefault(require("request-promise-native")); | ||
const p_event_1 = tslib_1.__importDefault(require("p-event")); | ||
const cacache = require('cacache'); | ||
@@ -34,2 +32,8 @@ const debug = debug_1.default('loopback:http-caching-proxy'); | ||
this._server = undefined; | ||
this._axios = axios_1.default.create({ | ||
// Provide a custom function to control when Axios throws errors based on | ||
// http status code. Please note that Axios creates a new error in such | ||
// condition and the original low-level error is lost | ||
validateStatus: () => true, | ||
}); | ||
} | ||
@@ -44,2 +48,3 @@ /** | ||
this._server.on('connect', (req, socket) => { | ||
// Reject tunneling requests | ||
socket.write('HTTP/1.1 501 Not Implemented\r\n\r\n'); | ||
@@ -68,4 +73,5 @@ socket.destroy(); | ||
this.logError(request, error); | ||
response.statusCode = error.name === 'RequestError' ? 502 : 500; | ||
response.end(error.message); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
response.statusCode = error.statusCode || 502; | ||
response.end(`${error.name}: ${error.message}`); | ||
}; | ||
@@ -111,14 +117,17 @@ try { | ||
debug('Forward request to %s %s', clientRequest.method, clientRequest.url); | ||
const backendResponse = await request_promise_native_1.default({ | ||
resolveWithFullResponse: true, | ||
simple: false, | ||
const backendResponse = await this._axios({ | ||
method: clientRequest.method, | ||
uri: clientRequest.url, | ||
url: clientRequest.url, | ||
headers: clientRequest.headers, | ||
body: clientRequest, | ||
data: clientRequest, | ||
// Set the response type to `arraybuffer` to force the `data` to be a | ||
// Buffer to allow ease of caching | ||
// Since this proxy is for testing only, buffering the entire | ||
// response body is acceptable. | ||
responseType: 'arraybuffer', | ||
timeout: this._options.timeout || undefined, | ||
}); | ||
debug('Got response for %s %s -> %s', clientRequest.method, clientRequest.url, backendResponse.statusCode, backendResponse.headers); | ||
debug('Got response for %s %s -> %s', clientRequest.method, clientRequest.url, backendResponse.status, backendResponse.headers, backendResponse.data); | ||
const metadata = { | ||
statusCode: backendResponse.statusCode, | ||
statusCode: backendResponse.status, | ||
headers: backendResponse.headers, | ||
@@ -137,7 +146,6 @@ createdAt: Date.now(), | ||
// the cache has not been updated yet. | ||
// Since this proxy is for testing only, buffering the entire | ||
// response body is acceptable. | ||
await cacache.put(this._options.cachePath, this._getCacheKey(clientRequest), backendResponse.body, { metadata }); | ||
clientResponse.writeHead(backendResponse.statusCode, backendResponse.headers); | ||
clientResponse.end(backendResponse.body); | ||
const data = backendResponse.data; | ||
await cacache.put(this._options.cachePath, this._getCacheKey(clientRequest), data, { metadata }); | ||
clientResponse.writeHead(backendResponse.status, backendResponse.headers); | ||
clientResponse.end(data); | ||
} | ||
@@ -147,6 +155,6 @@ logError(request, error) { | ||
if (this._options.logError) { | ||
console.error('Cannot proxy %s %s.', request.method, request.url, (_a = error.stack, (_a !== null && _a !== void 0 ? _a : error))); | ||
console.error('Cannot proxy %s %s.', request.method, request.url, (_a = error.stack) !== null && _a !== void 0 ? _a : error); | ||
} | ||
else { | ||
debug('Cannot proxy %s %s.', request.method, request.url, (_b = error.stack, (_b !== null && _b !== void 0 ? _b : error))); | ||
debug('Cannot proxy %s %s.', request.method, request.url, (_b = error.stack) !== null && _b !== void 0 ? _b : error); | ||
} | ||
@@ -153,0 +161,0 @@ } |
@@ -6,7 +6,5 @@ "use strict"; | ||
// License text available at https://opensource.org/licenses/MIT | ||
function __export(m) { | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
} | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__export(require("./http-caching-proxy")); | ||
const tslib_1 = require("tslib"); | ||
tslib_1.__exportStar(require("./http-caching-proxy"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
// Copyright IBM Corp. 2018. All Rights Reserved. | ||
// Copyright IBM Corp. 2018,2019. All Rights Reserved. | ||
// Node module: @loopback/http-caching-proxy | ||
@@ -3,0 +3,0 @@ // This file is licensed under the MIT License. |
@@ -1,2 +0,2 @@ | ||
// Copyright IBM Corp. 2018. All Rights Reserved. | ||
// Copyright IBM Corp. 2018,2019. All Rights Reserved. | ||
// Node module: @loopback/http-caching-proxy | ||
@@ -3,0 +3,0 @@ // This file is licensed under the MIT License. |
{ | ||
"name": "@loopback/http-caching-proxy", | ||
"version": "1.3.0", | ||
"version": "2.0.0", | ||
"description": "A caching HTTP proxy for integration tests. NOT SUITABLE FOR PRODUCTION USE!", | ||
"engines": { | ||
"node": ">=8.9" | ||
"node": ">=10" | ||
}, | ||
@@ -19,18 +19,19 @@ "scripts": { | ||
"dependencies": { | ||
"cacache": "^14.0.0", | ||
"axios": "^0.19.2", | ||
"cacache": "^15.0.0", | ||
"debug": "^4.1.1", | ||
"p-event": "^4.1.0", | ||
"request": "^2.88.0", | ||
"request-promise-native": "^1.0.8", | ||
"rimraf": "^3.0.1" | ||
"rimraf": "^3.0.2", | ||
"tslib": "^1.11.1" | ||
}, | ||
"devDependencies": { | ||
"@loopback/build": "^3.1.1", | ||
"@loopback/eslint-config": "^5.0.3", | ||
"@loopback/testlab": "^1.10.3", | ||
"@loopback/build": "^4.0.0", | ||
"@loopback/eslint-config": "^6.0.0", | ||
"@loopback/testlab": "^2.0.0", | ||
"@types/debug": "^4.1.5", | ||
"@types/node": "^10.17.14", | ||
"@types/request-promise-native": "^1.0.17", | ||
"@types/node": "^10.17.17", | ||
"@types/rimraf": "^2.0.3", | ||
"delay": "^4.3.0" | ||
"@types/tunnel": "0.0.1", | ||
"delay": "^4.3.0", | ||
"tunnel": "0.0.6" | ||
}, | ||
@@ -60,3 +61,3 @@ "keywords": [ | ||
}, | ||
"gitHead": "b5e53892d327c6cf4c6023055d2b38f13fe4729e" | ||
"gitHead": "baf9c89decba06b826204cd43e58a11be05408f8" | ||
} |
@@ -61,9 +61,18 @@ # @loopback/http-caching-proxy | ||
In your tests, configure the client library to use the caching proxy. Below is | ||
an example configuration for [request](https://www.npmjs.com/package/request): | ||
an example configuration for [axios](https://github.com/axios/axios): | ||
```ts | ||
request = request.defaults({ | ||
proxy: proxy.url, | ||
// Disable tunneling of HTTPS requests - this is required for HTTPS! | ||
tunnel: false, | ||
const parsed = new URL(proxy.url); | ||
const proxyConfig = { | ||
host: parsed.hostname, | ||
port: parseInt(parsed.port), | ||
protocol: parsed.protocol, | ||
auth: { | ||
username: parsed.username, | ||
password: parsed.password, | ||
}, | ||
}; | ||
const request = axios.create({ | ||
// Axios does not support proxy url directly | ||
proxy: proxyConfig, | ||
}); | ||
@@ -70,0 +79,0 @@ ``` |
@@ -6,2 +6,3 @@ // Copyright IBM Corp. 2018,2019. All Rights Reserved. | ||
import axios, {AxiosInstance, Method} from 'axios'; | ||
import debugFactory from 'debug'; | ||
@@ -17,3 +18,2 @@ import { | ||
import pEvent from 'p-event'; | ||
import makeRequest from 'request-promise-native'; | ||
@@ -72,2 +72,3 @@ const cacache = require('cacache'); | ||
export class HttpCachingProxy { | ||
private _axios: AxiosInstance; | ||
private _options: Required<ProxyOptions>; | ||
@@ -89,2 +90,8 @@ private _server?: HttpServer; | ||
this._server = undefined; | ||
this._axios = axios.create({ | ||
// Provide a custom function to control when Axios throws errors based on | ||
// http status code. Please note that Axios creates a new error in such | ||
// condition and the original low-level error is lost | ||
validateStatus: () => true, | ||
}); | ||
} | ||
@@ -103,2 +110,3 @@ | ||
this._server.on('connect', (req, socket) => { | ||
// Reject tunneling requests | ||
socket.write('HTTP/1.1 501 Not Implemented\r\n\r\n'); | ||
@@ -132,4 +140,5 @@ socket.destroy(); | ||
this.logError(request, error); | ||
response.statusCode = error.name === 'RequestError' ? 502 : 500; | ||
response.end(error.message); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
response.statusCode = (error as any).statusCode || 502; | ||
response.end(`${error.name}: ${error.message}`); | ||
}; | ||
@@ -196,10 +205,13 @@ | ||
debug('Forward request to %s %s', clientRequest.method, clientRequest.url); | ||
const backendResponse = await makeRequest({ | ||
resolveWithFullResponse: true, | ||
simple: false, | ||
method: clientRequest.method, | ||
uri: clientRequest.url!, | ||
const backendResponse = await this._axios({ | ||
method: clientRequest.method as Method, | ||
url: clientRequest.url!, | ||
headers: clientRequest.headers, | ||
body: clientRequest, | ||
data: clientRequest, | ||
// Set the response type to `arraybuffer` to force the `data` to be a | ||
// Buffer to allow ease of caching | ||
// Since this proxy is for testing only, buffering the entire | ||
// response body is acceptable. | ||
responseType: 'arraybuffer', | ||
timeout: this._options.timeout || undefined, | ||
@@ -212,8 +224,9 @@ }); | ||
clientRequest.url, | ||
backendResponse.statusCode, | ||
backendResponse.status, | ||
backendResponse.headers, | ||
backendResponse.data, | ||
); | ||
const metadata: CachedMetadata = { | ||
statusCode: backendResponse.statusCode, | ||
statusCode: backendResponse.status, | ||
headers: backendResponse.headers, | ||
@@ -233,17 +246,14 @@ createdAt: Date.now(), | ||
// the cache has not been updated yet. | ||
// Since this proxy is for testing only, buffering the entire | ||
// response body is acceptable. | ||
const data = backendResponse.data; | ||
await cacache.put( | ||
this._options.cachePath, | ||
this._getCacheKey(clientRequest), | ||
backendResponse.body, | ||
data, | ||
{metadata}, | ||
); | ||
clientResponse.writeHead( | ||
backendResponse.statusCode, | ||
backendResponse.headers, | ||
); | ||
clientResponse.end(backendResponse.body); | ||
clientResponse.writeHead(backendResponse.status, backendResponse.headers); | ||
clientResponse.end(data); | ||
} | ||
@@ -250,0 +260,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
44632
468
109
9
+ Addedaxios@^0.19.2
+ Addedtslib@^1.11.1
+ Added@gar/promisify@1.1.3(transitive)
+ Added@npmcli/fs@1.1.1(transitive)
+ Added@npmcli/move-file@1.1.2(transitive)
+ Addedaxios@0.19.2(transitive)
+ Addedcacache@15.3.0(transitive)
+ Addedfollow-redirects@1.5.10(transitive)
+ Addedlru-cache@6.0.0(transitive)
+ Addedp-map@4.0.0(transitive)
+ Addedsemver@7.7.1(transitive)
+ Addedssri@8.0.1(transitive)
+ Addedtslib@1.14.1(transitive)
- Removedrequest@^2.88.0
- Removedrequest-promise-native@^1.0.8
- Removedajv@6.12.6(transitive)
- Removedaproba@1.2.0(transitive)
- Removedasn1@0.2.6(transitive)
- Removedassert-plus@1.0.0(transitive)
- Removedasynckit@0.4.0(transitive)
- Removedaws-sign2@0.7.0(transitive)
- Removedaws4@1.13.2(transitive)
- Removedbcrypt-pbkdf@1.0.2(transitive)
- Removedcacache@14.0.0(transitive)
- Removedcaseless@0.12.0(transitive)
- Removedchownr@1.1.4(transitive)
- Removedcombined-stream@1.0.8(transitive)
- Removedcopy-concurrently@1.0.5(transitive)
- Removedcore-util-is@1.0.21.0.3(transitive)
- Removeddashdash@1.14.1(transitive)
- Removeddelayed-stream@1.0.0(transitive)
- Removedecc-jsbn@0.1.2(transitive)
- Removedextend@3.0.2(transitive)
- Removedextsprintf@1.3.0(transitive)
- Removedfast-deep-equal@3.1.3(transitive)
- Removedfast-json-stable-stringify@2.1.0(transitive)
- Removedfiggy-pudding@3.5.2(transitive)
- Removedforever-agent@0.6.1(transitive)
- Removedform-data@2.3.3(transitive)
- Removedfs-write-stream-atomic@1.0.10(transitive)
- Removedgetpass@0.1.7(transitive)
- Removedgraceful-fs@4.2.11(transitive)
- Removedhar-schema@2.0.0(transitive)
- Removedhar-validator@5.1.5(transitive)
- Removedhttp-signature@1.2.0(transitive)
- Removediferr@0.1.5(transitive)
- Removedis-typedarray@1.0.0(transitive)
- Removedisarray@1.0.0(transitive)
- Removedisstream@0.1.2(transitive)
- Removedjsbn@0.1.1(transitive)
- Removedjson-schema@0.4.0(transitive)
- Removedjson-schema-traverse@0.4.1(transitive)
- Removedjson-stringify-safe@5.0.1(transitive)
- Removedjsprim@1.4.2(transitive)
- Removedlodash@4.17.21(transitive)
- Removedlru-cache@5.1.1(transitive)
- Removedmime-db@1.52.0(transitive)
- Removedmime-types@2.1.35(transitive)
- Removedminimist@1.2.8(transitive)
- Removedmkdirp@0.5.6(transitive)
- Removedmove-concurrently@1.0.1(transitive)
- Removedoauth-sign@0.9.0(transitive)
- Removedp-map@3.0.0(transitive)
- Removedperformance-now@2.1.0(transitive)
- Removedprocess-nextick-args@2.0.1(transitive)
- Removedpsl@1.15.0(transitive)
- Removedpunycode@2.3.1(transitive)
- Removedqs@6.5.3(transitive)
- Removedreadable-stream@2.3.8(transitive)
- Removedrequest@2.88.2(transitive)
- Removedrequest-promise-core@1.1.4(transitive)
- Removedrequest-promise-native@1.0.9(transitive)
- Removedrimraf@2.7.1(transitive)
- Removedrun-queue@1.0.3(transitive)
- Removedsafe-buffer@5.1.2(transitive)
- Removedsafer-buffer@2.1.2(transitive)
- Removedsshpk@1.18.0(transitive)
- Removedssri@7.1.1(transitive)
- Removedstealthy-require@1.1.1(transitive)
- Removedstring_decoder@1.1.1(transitive)
- Removedtough-cookie@2.5.0(transitive)
- Removedtunnel-agent@0.6.0(transitive)
- Removedtweetnacl@0.14.5(transitive)
- Removeduri-js@4.4.1(transitive)
- Removedutil-deprecate@1.0.2(transitive)
- Removeduuid@3.4.0(transitive)
- Removedverror@1.10.0(transitive)
- Removedyallist@3.1.1(transitive)
Updatedcacache@^15.0.0
Updatedrimraf@^3.0.2