Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 🎸 node, use node-fetch instead of xmlhttprequest #159

Merged
merged 1 commit into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

| Statements | Branches | Functions | Lines |
| --------------------------- | ----------------------- | ------------------------- | ----------------- |
| ![Statements](https://img.shields.io/badge/statements-96.18%25-brightgreen.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-93.46%25-brightgreen.svg?style=flat) | ![Functions](https://img.shields.io/badge/functions-96.71%25-brightgreen.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-96.34%25-brightgreen.svg?style=flat) |
| ![Statements](https://img.shields.io/badge/statements-50%25-red.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-36.91%25-red.svg?style=flat) | ![Functions](https://img.shields.io/badge/functions-46%25-red.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-51.31%25-red.svg?style=flat) |


## 1. Introduction
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"isomorphic-fetch": "^3.0.0",
"js-sha256": "^0.9.0",
"keccak": "^3.0.3",
"node-fetch": "2",
"query-string": "^7.1.3",
"randombytes": "^2.1.0",
"readable-stream": "^4.3.0",
Expand Down
25 changes: 21 additions & 4 deletions src/util/httpProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const defaultHeaders = {
};

let RequestLibrary = {};
let RequestLibraryXMLOnly = null;
let isFetch = false;
if (process.env.RUNTIME_ENV === 'browser') {
// For browsers use DOM Api XMLHttpRequest
Expand All @@ -27,18 +28,24 @@ if (process.env.RUNTIME_ENV === 'browser') {
} else {
// For node use xmlhttprequest
// eslint-disable-next-line global-require
RequestLibrary = require('xmlhttprequest').XMLHttpRequest;
RequestLibraryXMLOnly = require('xmlhttprequest').XMLHttpRequest;
// eslint-disable-next-line global-require
RequestLibrary = require('node-fetch');
isFetch = true;
}

export default class HttpProvider {
constructor(
host = 'http://localhost:8545',
timeout = 8000,
headers = defaultHeaders
headers = defaultHeaders,
// support node-fetch options
options = {}
) {
this.host = host.replace(/\/$/, '');
this.timeout = timeout;
this.headers = {};
this.options = options;
if (Array.isArray(headers)) {
headers.forEach(({ name, value }) => {
this.headers[name] = value;
Expand Down Expand Up @@ -112,6 +119,7 @@ export default class HttpProvider {
myHeaders.append(header, this.headers[header]);
});
return request(uri, {
...this.options,
method: method.toUpperCase(),
headers: myHeaders,
body,
Expand Down Expand Up @@ -179,8 +187,17 @@ export default class HttpProvider {
}

send(requestConfig) {
if (isFetch) throw new Error("Can not get XMLHttpRequest, invalid parameter: 'sync'");
const request = new RequestLibrary();
let request;
if (isFetch) {
if (!RequestLibraryXMLOnly) {
// browser case, Chrome extension v3.
throw new Error("Can not get XMLHttpRequest, invalid parameter: 'sync'");
} else {
request = new RequestLibraryXMLOnly();
}
} else {
request = new RequestLibrary();
}
request.withCredentials = false;
this.requestSend(requestConfig, request);
let result = request.responseText;
Expand Down
4 changes: 2 additions & 2 deletions test/unit/util/httpProvider.browser-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ describe('test httpProvider', () => {
fetch
);
const result = await response.text();
expect(JSON.parse(result)).toEqual({
expect(JSON.parse(result)).toMatchObject({
Success: false,
TransactionFee: null,
ResourceFee: null,
Expand Down Expand Up @@ -401,7 +401,7 @@ describe('test httpProvider', () => {
request
);
const result = request.responseText;
expect(JSON.parse(result)).toEqual({
expect(JSON.parse(result)).toMatchObject({
Success: false,
TransactionFee: null,
ResourceFee: null,
Expand Down
27 changes: 27 additions & 0 deletions test/unit/util/httpProvider.data.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

139 changes: 139 additions & 0 deletions test/unit/util/httpProvider.fetch.node-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import HttpProvider from '../../../src/util/httpProvider';
import http from 'node:http';
import https from 'node:https';
import { blockByHeightRes } from './httpProvider.data';
const fetch = require('node-fetch');
const stageEndpoint = 'https://aelf-public-node.aelf.io/';
// for test timeout
jest.useFakeTimers();
jest.spyOn(global, 'setTimeout');

describe('test httpProvider', () => {
beforeEach(() => {
jest.resetModules();
});

test('test get request send by fetch', async () => {
const httpProvider = new HttpProvider(stageEndpoint);
const response = await httpProvider.requestSendByFetch(
{
url: 'blockChain/blockByHeight',
method: 'GET',
params: {
blockHeight: 136240697,
},
},
fetch
);
const result = await response.text();
expect(JSON.parse(result)).toEqual(blockByHeightRes);
});
test('test get request send by fetch, keepalive', async () => {
const httpAgent = new http.Agent({
keepAlive: true
});
const httpsAgent = new https.Agent({
keepAlive: true
});
const options = {
agent: function(_parsedURL) {
if (_parsedURL.protocol === 'http:') {
return httpAgent;
} else {
return httpsAgent;
}
}
};

const httpProvider = new HttpProvider(stageEndpoint, 8000, {}, options);
const response = await httpProvider.requestSendByFetch(
{
url: 'blockChain/blockByHeight',
method: 'GET',
params: {
blockHeight: 136240697,
},
},
fetch
);
const result = await response.text();
expect(JSON.parse(result)).toEqual(blockByHeightRes);
});
test('test post request send by fetch', async () => {
const httpProvider = new HttpProvider(stageEndpoint);
const response = await httpProvider.requestSendByFetch(
{
url: 'blockChain/calculateTransactionFee',
params: {
RawTransaction:
'0a220a2005c3b3959caeee55b5db4004f6f9d76860aae818ce7b33d210a446ecb275468212220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba18a8a19e022204fa60011c2a085472616e73666572322e0a220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba1203454c461880c2d72f82f10441ad1647aa462a8859c7a699f22d6124c82a5239c90746ac67ebfd8e1a7b4a25f343733351162d205fc881ea62072e9fe0fad5f6113734309b6666f6812d6b7a6400',
},
},
fetch
);
const result = await response.text();
expect(JSON.parse(result)).toMatchObject({
Success: false,
TransactionFee: null,
ResourceFee: null,
});
});
test('test send async by fetch', async () => {
const httpProvider = new HttpProvider(stageEndpoint);
const result = await httpProvider.sendAsyncByFetch({
url: 'blockChain/blockByHeight',
method: 'GET',
params: {
blockHeight: 136240697,
},
});
expect(result).toEqual(blockByHeightRes);
});

test('test send async by fetch when error', async () => {
const httpProvider = new HttpProvider(stageEndpoint);
await expect(
httpProvider.sendAsyncByFetch({
url: 'blockChain/executeTransaction',
method: 'POST',
params: {
RawTransaction: '111',
},
})
).rejects.toEqual({
Error: {
Code: '20012',
Message: 'Invalid params',
Details: null,
Data: {},
ValidationErrors: null,
},
});
});

test('test send by fetch', () => {
const httpProvider = new HttpProvider(stageEndpoint);
try {
httpProvider.send({
url: 'blockChain/blockHeight',
method: 'GET',
});
} catch (e) {
expect(e).toEqual(
new Error("Can not get XMLHttpRequest, invalid parameter: 'sync'")
);
}
});

test('test send async by fetch method', async () => {
const httpProvider = new HttpProvider(stageEndpoint);
const result = await httpProvider.sendAsync({
url: 'blockChain/blockByHeight',
method: 'GET',
params: {
blockHeight: 136240697,
},
});
expect(result).toEqual(blockByHeightRes);
});
});
63 changes: 37 additions & 26 deletions test/unit/util/requestManage.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,27 @@ describe('test requestManage', () => {
test('test send with provider', () => {
const httpProvider = new HttpProvider('https://aelf-public-node.aelf.io');
const requestManage = new RequestManager(httpProvider);
const result = requestManage.send({
requestMethod: 'post',
method: 'blockChain/calculateTransactionFee',
params: {
RawTransaction:
'0a220a2005c3b3959caeee55b5db4004f6f9d76860aae818ce7b33d210a446ecb275468212220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba18a8a19e022204fa60011c2a085472616e73666572322e0a220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba1203454c461880c2d72f82f10441ad1647aa462a8859c7a699f22d6124c82a5239c90746ac67ebfd8e1a7b4a25f343733351162d205fc881ea62072e9fe0fad5f6113734309b6666f6812d6b7a6400',
},
});
expect(result).toEqual({
Success: false,
TransactionFee: null,
ResourceFee: null,
});
try {
const result = requestManage.send({
requestMethod: 'post',
method: 'blockChain/calculateTransactionFee',
params: {
RawTransaction:
'0a220a2005c3b3959caeee55b5db4004f6f9d76860aae818ce7b33d210a446ecb275468212220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba18a8a19e022204fa60011c2a085472616e73666572322e0a220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba1203454c461880c2d72f82f10441ad1647aa462a8859c7a699f22d6124c82a5239c90746ac67ebfd8e1a7b4a25f343733351162d205fc881ea62072e9fe0fad5f6113734309b6666f6812d6b7a6400',
},
});
expect(result).toMatchObject({
Success: false,
TransactionFee: null,
ResourceFee: null,
});
} catch(error) {
expect(error).toMatchObject({
Success: false,
TransactionFee: null,
ResourceFee: null,
});
}
});
test('test send without provider', () => {
const requestManage = new RequestManager();
Expand All @@ -61,19 +69,22 @@ describe('test requestManage', () => {
test('test send async with provider', async () => {
const httpProvider = new HttpProvider('https://aelf-public-node.aelf.io');
const requestManage = new RequestManager(httpProvider);
const result = await requestManage.sendAsync({
requestMethod: 'post',
method: 'blockChain/calculateTransactionFee',
params: {
RawTransaction:
'0a220a2005c3b3959caeee55b5db4004f6f9d76860aae818ce7b33d210a446ecb275468212220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba18a8a19e022204fa60011c2a085472616e73666572322e0a220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba1203454c461880c2d72f82f10441ad1647aa462a8859c7a699f22d6124c82a5239c90746ac67ebfd8e1a7b4a25f343733351162d205fc881ea62072e9fe0fad5f6113734309b6666f6812d6b7a6400',
},
});
expect(result).toEqual({
Success: false,
TransactionFee: null,
ResourceFee: null,
});
try {
const result = await requestManage.sendAsync({
requestMethod: 'post',
method: 'blockChain/calculateTransactionFee',
params: {
RawTransaction:
'0a220a2005c3b3959caeee55b5db4004f6f9d76860aae818ce7b33d210a446ecb275468212220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba18a8a19e022204fa60011c2a085472616e73666572322e0a220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba1203454c461880c2d72f82f10441ad1647aa462a8859c7a699f22d6124c82a5239c90746ac67ebfd8e1a7b4a25f343733351162d205fc881ea62072e9fe0fad5f6113734309b6666f6812d6b7a6400',
},
});
} catch (error) {
expect(error).toMatchObject({
Success: false,
TransactionFee: null,
ResourceFee: null,
});
}
});
test('test send async without provider', async () => {
const requestManage = new RequestManager();
Expand Down
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8180,6 +8180,13 @@ node-addon-api@^2.0.0:
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32"
integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==

node-fetch@2:
version "2.7.0"
resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
dependencies:
whatwg-url "^5.0.0"

node-fetch@^2.6.1, node-fetch@^2.6.7:
version "2.6.9"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6"
Expand Down
Loading