only allow body to be consumed once, add some tests
This commit is contained in:
parent
c3071e3059
commit
f92bd99968
@ -7,22 +7,32 @@ class Response {
|
|||||||
this.cacheFilePath = cacheFilePath;
|
this.cacheFilePath = cacheFilePath;
|
||||||
this.headers = new Headers(raw.headers);
|
this.headers = new Headers(raw.headers);
|
||||||
this.fromCache = fromCache;
|
this.fromCache = fromCache;
|
||||||
|
this.consumed = false;
|
||||||
|
|
||||||
if (this.bodyBuffer.type === 'Buffer') {
|
if (this.bodyBuffer.type === 'Buffer') {
|
||||||
this.bodyBuffer = Buffer.from(this.bodyBuffer);
|
this.bodyBuffer = Buffer.from(this.bodyBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
consumeBody() {
|
||||||
|
if (this.consumed) {
|
||||||
|
throw new Error('Error: body used already');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.consumed = true;
|
||||||
|
return this.bodyBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
text() {
|
text() {
|
||||||
return this.bodyBuffer.toString();
|
return this.consumeBody().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
json() {
|
json() {
|
||||||
return JSON.parse(this.bodyBuffer.toString());
|
return JSON.parse(this.consumeBody().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer() {
|
buffer() {
|
||||||
return this.bodyBuffer;
|
return this.consumeBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
async ejectFromCache() {
|
async ejectFromCache() {
|
||||||
|
4
index.js
4
index.js
@ -3,7 +3,6 @@ const fs = require('fs');
|
|||||||
const { URLSearchParams } = require('url');
|
const { URLSearchParams } = require('url');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const Response = require('./classes/response.js');
|
const Response = require('./classes/response.js');
|
||||||
|
|
||||||
const CACHE_VERSION = 2;
|
const CACHE_VERSION = 2;
|
||||||
@ -12,6 +11,9 @@ function md5(str) {
|
|||||||
return crypto.createHash('md5').update(str).digest('hex');
|
return crypto.createHash('md5').update(str).digest('hex');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Since the bounday in FormData is random,
|
||||||
|
// we ignore it for purposes of calculating
|
||||||
|
// the cache key.
|
||||||
function getFormDataCacheKey(formData) {
|
function getFormDataCacheKey(formData) {
|
||||||
const cacheKey = { ...formData };
|
const cacheKey = { ...formData };
|
||||||
|
|
||||||
|
@ -7,11 +7,15 @@ const FetchCache = require('../index.js');
|
|||||||
const { URLSearchParams } = require('url');
|
const { URLSearchParams } = require('url');
|
||||||
|
|
||||||
const CACHE_PATH = path.join(__dirname, '..', '.cache');
|
const CACHE_PATH = path.join(__dirname, '..', '.cache');
|
||||||
|
const expectedPngBuffer = fs.readFileSync(path.join(__dirname, 'expected_png.png'));
|
||||||
|
|
||||||
const TWO_HUNDRED_URL = 'https://httpbin.org/status/200';
|
const TWO_HUNDRED_URL = 'https://httpbin.org/status/200';
|
||||||
const FOUR_HUNDRED_URL = 'https://httpbin.org/status/400';
|
const FOUR_HUNDRED_URL = 'https://httpbin.org/status/400';
|
||||||
const THREE_HUNDRED_TWO_URL = 'https://httpbin.org/status/302';
|
const THREE_HUNDRED_TWO_URL = 'https://httpbin.org/status/302';
|
||||||
const TEXT_BODY_URL = 'https://httpbin.org/robots.txt';
|
const TEXT_BODY_URL = 'https://httpbin.org/robots.txt';
|
||||||
|
const JSON_BODY_URL = 'https://httpbin.org/json';
|
||||||
|
const PNG_BODY_URL = 'https://httpbin.org/image/png';
|
||||||
|
|
||||||
const TEXT_BODY_EXPECTED = 'User-agent: *\nDisallow: /deny\n';
|
const TEXT_BODY_EXPECTED = 'User-agent: *\nDisallow: /deny\n';
|
||||||
|
|
||||||
let fetch;
|
let fetch;
|
||||||
@ -195,13 +199,51 @@ describe('Cache tests', function() {
|
|||||||
}).timeout(10000);
|
}).timeout(10000);
|
||||||
|
|
||||||
describe('Data tests', function() {
|
describe('Data tests', function() {
|
||||||
|
it('Refuses to consume body twice', async function() {
|
||||||
|
res = await fetch(TEXT_BODY_URL);
|
||||||
|
await res.text();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await res.text();
|
||||||
|
throw new Error('The above line should have thrown.');
|
||||||
|
} catch (err) {
|
||||||
|
// It threw
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it('Can get text body', async function() {
|
it('Can get text body', async function() {
|
||||||
res = await fetch(TEXT_BODY_URL);
|
res = await fetch(TEXT_BODY_URL);
|
||||||
body = await res.text();
|
body = await res.text();
|
||||||
assert.strictEqual(body, TEXT_BODY_EXPECTED);
|
assert.strictEqual(body, TEXT_BODY_EXPECTED);
|
||||||
|
assert.strictEqual(res.fromCache, false);
|
||||||
|
|
||||||
res = await fetch(TEXT_BODY_URL);
|
res = await fetch(TEXT_BODY_URL);
|
||||||
body = await res.text();
|
body = await res.text();
|
||||||
assert.strictEqual(body, TEXT_BODY_EXPECTED);
|
assert.strictEqual(body, TEXT_BODY_EXPECTED);
|
||||||
|
assert.strictEqual(res.fromCache, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Can get JSON body', async function() {
|
||||||
|
res = await fetch(JSON_BODY_URL);
|
||||||
|
body = await res.json();
|
||||||
|
assert(body.slideshow);
|
||||||
|
assert.strictEqual(res.fromCache, false);
|
||||||
|
|
||||||
|
res = await fetch(JSON_BODY_URL);
|
||||||
|
body = await res.json();
|
||||||
|
assert(body.slideshow);
|
||||||
|
assert.strictEqual(res.fromCache, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Can get PNG buffer body', async function() {
|
||||||
|
res = await fetch(PNG_BODY_URL);
|
||||||
|
body = await res.buffer();
|
||||||
|
assert.strictEqual(expectedPngBuffer.equals(body), true);
|
||||||
|
assert.strictEqual(res.fromCache, false);
|
||||||
|
|
||||||
|
res = await fetch(PNG_BODY_URL);
|
||||||
|
body = await res.buffer();
|
||||||
|
assert.strictEqual(expectedPngBuffer.equals(body), true);
|
||||||
|
assert.strictEqual(res.fromCache, true);
|
||||||
});
|
});
|
||||||
}).timeout(10000);
|
}).timeout(10000);
|
||||||
|
Reference in New Issue
Block a user