cvitool 1.0.7 → 1.0.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,6 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { Encoding } from 'crypto';
1
4
  interface randomStringOptions {
2
5
  special?: boolean;
3
6
  lowercase?: boolean;
@@ -6,4 +9,8 @@ interface randomStringOptions {
6
9
  specials?: string;
7
10
  }
8
11
  declare function randomString(length: number, options?: randomStringOptions): string;
9
- export { randomStringOptions, randomString };
12
+ declare function encryptCBC(data: string, length: 128 | 192 | 256, key: Buffer, iv: Buffer, inputEncoding?: Encoding): string;
13
+ declare function decryptCBC(encryptData: string, length: 128 | 192 | 256, key: Buffer, iv: Buffer, outputEncoding?: Encoding): string;
14
+ declare function md5(data: string, inputEncoding?: Encoding): string;
15
+ declare function execCmdCommand(command: string): Promise<unknown>;
16
+ export { randomStringOptions, randomString, encryptCBC, decryptCBC, md5, execCmdCommand };
@@ -1,7 +1,17 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.randomString = void 0;
12
+ exports.execCmdCommand = exports.md5 = exports.decryptCBC = exports.encryptCBC = exports.randomString = void 0;
4
13
  const crypto_1 = require("crypto");
14
+ const child_process_1 = require("child_process");
5
15
  function randomString(length, options) {
6
16
  let { special = false, lowercase = true, upperCase = true, number = true, specials } = options || {};
7
17
  if (specials) {
@@ -35,3 +45,50 @@ function randomString(length, options) {
35
45
  return result;
36
46
  }
37
47
  exports.randomString = randomString;
48
+ function encryptCBC(data, length, key, iv, inputEncoding = 'utf-8') {
49
+ const algorithm = `aes-${length}-cbc`;
50
+ const cipher = (0, crypto_1.createCipheriv)(algorithm, key, iv);
51
+ let crypted = cipher.update(data, inputEncoding, 'hex');
52
+ crypted += cipher.final('hex');
53
+ return crypted;
54
+ }
55
+ exports.encryptCBC = encryptCBC;
56
+ ;
57
+ function decryptCBC(encryptData, length, key, iv, outputEncoding = 'utf-8') {
58
+ const algorithm = `aes-${length}-cbc`;
59
+ const decipher = (0, crypto_1.createDecipheriv)(algorithm, key, iv);
60
+ let decrypted = decipher.update(encryptData, 'hex', outputEncoding);
61
+ decrypted += decipher.final(outputEncoding);
62
+ return decrypted;
63
+ }
64
+ exports.decryptCBC = decryptCBC;
65
+ ;
66
+ function md5(data, inputEncoding = 'utf-8') {
67
+ return (0, crypto_1.createHash)('md5').update(data, inputEncoding).digest('hex');
68
+ }
69
+ exports.md5 = md5;
70
+ function execCmdCommand(command) {
71
+ return __awaiter(this, void 0, void 0, function* () {
72
+ const commandList = command.split(' ');
73
+ const commandName = commandList.splice(0, 1);
74
+ return new Promise((resolve, reject) => {
75
+ const chunks = [];
76
+ const cmd = (0, child_process_1.spawn)(commandName[0], commandList, { stdio: 'pipe', shell: true });
77
+ cmd.stdout.on('data', chunk => {
78
+ chunks.push(chunk);
79
+ });
80
+ cmd.stderr.on('data', chunk => {
81
+ chunks.push(chunk);
82
+ });
83
+ cmd.on('exit', (code) => {
84
+ const result = Buffer.concat(chunks).toString();
85
+ if (code !== 0) {
86
+ reject(result);
87
+ return;
88
+ }
89
+ resolve(result);
90
+ });
91
+ });
92
+ });
93
+ }
94
+ exports.execCmdCommand = execCmdCommand;
@@ -12,14 +12,16 @@ interface CustomObject {
12
12
  }
13
13
  interface baseReqOptions {
14
14
  timeout?: number;
15
- method?: Method;
16
15
  agent?: http.Agent | https.Agent;
17
16
  headers?: {
18
17
  [key: string]: string;
19
18
  };
20
19
  resType?: ResType;
20
+ connectTimeOut?: number;
21
+ readTimeOut?: number;
21
22
  }
22
23
  interface reqOptions extends baseReqOptions {
24
+ method?: Method;
23
25
  query?: {
24
26
  [key: string]: string;
25
27
  };
@@ -28,9 +30,11 @@ interface reqOptions extends baseReqOptions {
28
30
  };
29
31
  }
30
32
  interface reqSendBufferOptions extends baseReqOptions {
33
+ method?: Method;
31
34
  buffer: Buffer;
32
35
  }
33
36
  interface reqSendStreamOptions extends baseReqOptions {
37
+ method?: Method;
34
38
  stream: ReadStream;
35
39
  }
36
40
  interface reqSendMultiPartOptions extends baseReqOptions {
@@ -45,4 +49,8 @@ declare function request(url: string, options?: reqOptions): Promise<ResData>;
45
49
  declare function reqSendBuffer(url: string, options: reqSendBufferOptions): Promise<ResData>;
46
50
  declare function reqSendStream(url: string, options: reqSendStreamOptions): Promise<ResData>;
47
51
  declare function reqSendMultiPart(url: string, options: reqSendMultiPartOptions): Promise<ResData>;
48
- export { reqOptions, reqSendBufferOptions, reqSendStreamOptions, reqSendMultiPartOptions, ResData, request, reqSendBuffer, reqSendStream, reqSendMultiPart, };
52
+ declare function get(url: string, options?: Omit<reqOptions, 'method'>): Promise<ResData>;
53
+ declare function post(url: string, options?: Omit<reqOptions, 'method'>): Promise<ResData>;
54
+ declare function put(url: string, options?: Omit<reqOptions, 'method'>): Promise<ResData>;
55
+ declare function head(url: string, options?: Omit<reqOptions, 'method'>): Promise<ResData>;
56
+ export { reqOptions, reqSendBufferOptions, reqSendStreamOptions, reqSendMultiPartOptions, ResData, request, reqSendBuffer, reqSendStream, reqSendMultiPart, get, post, put, head };
package/build/src/hgo.js CHANGED
@@ -9,19 +9,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.reqSendMultiPart = exports.reqSendStream = exports.reqSendBuffer = exports.request = void 0;
12
+ exports.head = exports.put = exports.post = exports.get = exports.reqSendMultiPart = exports.reqSendStream = exports.reqSendBuffer = exports.request = void 0;
13
13
  const querystring = require("querystring");
14
14
  const https = require("https");
15
15
  const http = require("http");
16
- function getTimeOutMessage(timeout) {
17
- return `request timeout of ${timeout} ms`;
16
+ function buildTimeOutErr(type, timeout, reqUrl) {
17
+ const err = new Error();
18
+ err.code = 'TimeOut';
19
+ err.name = `${type}Error`;
20
+ err.message = `${type} for ${timeout} ms`;
21
+ err.reqUrl = reqUrl;
22
+ return err;
18
23
  }
19
24
  function getProtocol(url) {
20
25
  return url.startsWith('https') ? https : http;
21
26
  }
22
27
  function request(url, options) {
23
28
  return __awaiter(this, void 0, void 0, function* () {
24
- const { query = {}, body = {}, headers = {}, timeout = 5000, method = 'get', agent, resType = 'json' } = options || {};
29
+ let { query = {}, body = {}, headers = {}, timeout = 5000, method = 'get', agent, resType = 'json', connectTimeOut, readTimeOut } = options || {};
30
+ if (timeout && !(connectTimeOut && readTimeOut)) {
31
+ connectTimeOut = timeout;
32
+ readTimeOut = timeout;
33
+ }
25
34
  if (Object.keys(query).length !== 0) {
26
35
  if (url.indexOf('?') > -1) {
27
36
  url = url + '&' + querystring.stringify(query);
@@ -33,22 +42,25 @@ function request(url, options) {
33
42
  const data = JSON.stringify(body);
34
43
  const protocol = getProtocol(url);
35
44
  const isbodyEmpty = Object.keys(body).length === 0;
36
- const baseHeaders = {
37
- 'Content-Type': 'application/json;charset=utf-8',
38
- 'Content-length': isbodyEmpty ? 0 : Buffer.byteLength(data)
39
- };
45
+ let baseHeaders = {};
46
+ if (!isbodyEmpty) {
47
+ baseHeaders = {
48
+ 'Content-Type': 'application/json; charset=utf-8',
49
+ 'Content-length': Buffer.byteLength(data)
50
+ };
51
+ }
40
52
  return new Promise((resolve, reject) => {
41
53
  const req = protocol.request(url, {
42
- timeout,
54
+ timeout: connectTimeOut,
43
55
  headers: Object.assign(headers, baseHeaders),
44
56
  method,
45
57
  agent
46
58
  }, res => {
47
- resHandld(res, resolve, reject, resType, method);
59
+ resHandld(res, resolve, reject, resType, method, readTimeOut, req);
48
60
  });
49
61
  req.on('timeout', () => {
50
62
  req.destroy();
51
- reject(new Error(getTimeOutMessage(timeout)));
63
+ reject(buildTimeOutErr('connectTimeOut', connectTimeOut, url));
52
64
  });
53
65
  req.on('error', e => {
54
66
  req.destroy();
@@ -72,20 +84,24 @@ function request(url, options) {
72
84
  exports.request = request;
73
85
  function reqSendBuffer(url, options) {
74
86
  return __awaiter(this, void 0, void 0, function* () {
75
- const { timeout = 60000, headers = {}, buffer, method = 'post', agent, resType = 'json' } = options;
87
+ let { timeout = 5000, headers = {}, buffer, method = 'post', agent, resType = 'json', connectTimeOut, readTimeOut } = options;
88
+ if (timeout && !(connectTimeOut && readTimeOut)) {
89
+ connectTimeOut = timeout;
90
+ readTimeOut = timeout;
91
+ }
76
92
  const protocol = getProtocol(url);
77
93
  return new Promise((resolve, reject) => {
78
94
  const req = protocol.request(url, {
79
- timeout,
95
+ timeout: connectTimeOut,
80
96
  headers: Object.assign(headers, { 'Content-Length': buffer.byteLength }),
81
97
  method,
82
98
  agent
83
99
  }, res => {
84
- resHandld(res, resolve, reject, resType, method);
100
+ resHandld(res, resolve, reject, resType, method, readTimeOut, req);
85
101
  });
86
102
  req.on('timeout', () => {
87
103
  req.destroy();
88
- reject(new Error(getTimeOutMessage(timeout)));
104
+ reject(buildTimeOutErr('connectTimeOut', connectTimeOut, url));
89
105
  });
90
106
  req.on('error', e => {
91
107
  req.destroy();
@@ -104,7 +120,11 @@ function reqSendBuffer(url, options) {
104
120
  exports.reqSendBuffer = reqSendBuffer;
105
121
  function reqSendStream(url, options) {
106
122
  return __awaiter(this, void 0, void 0, function* () {
107
- const { timeout = 60000, method = 'post', stream, headers = {}, agent, resType = 'json' } = options;
123
+ let { timeout = 5000, method = 'post', stream, headers = {}, agent, resType = 'json', connectTimeOut, readTimeOut } = options;
124
+ if (timeout && !(connectTimeOut && readTimeOut)) {
125
+ connectTimeOut = timeout;
126
+ readTimeOut = timeout;
127
+ }
108
128
  const protocol = getProtocol(url);
109
129
  return new Promise((resolve, reject) => {
110
130
  const baseHeaders = {
@@ -113,16 +133,16 @@ function reqSendStream(url, options) {
113
133
  Connection: 'keep-alive'
114
134
  };
115
135
  const req = protocol.request(url, {
116
- timeout,
136
+ timeout: connectTimeOut,
117
137
  headers: Object.assign(headers, baseHeaders),
118
138
  method,
119
139
  agent
120
140
  }, res => {
121
- resHandld(res, resolve, reject, resType, method);
141
+ resHandld(res, resolve, reject, resType, method, readTimeOut, req);
122
142
  });
123
143
  req.on('timeout', () => {
124
144
  req.destroy();
125
- reject(new Error(getTimeOutMessage(timeout)));
145
+ reject(buildTimeOutErr('connectTimeOut', connectTimeOut, url));
126
146
  });
127
147
  req.on('error', e => {
128
148
  req.destroy();
@@ -151,20 +171,24 @@ function reqSendStream(url, options) {
151
171
  exports.reqSendStream = reqSendStream;
152
172
  function reqSendMultiPart(url, options) {
153
173
  return __awaiter(this, void 0, void 0, function* () {
154
- const { timeout = 60000, headers = {}, form, agent, resType = 'json' } = options;
174
+ let { timeout = 60000, headers = {}, form, agent, resType = 'json', connectTimeOut, readTimeOut } = options;
175
+ if (timeout && !(connectTimeOut && readTimeOut)) {
176
+ connectTimeOut = timeout;
177
+ readTimeOut = timeout;
178
+ }
155
179
  const protocol = getProtocol(url);
156
180
  return new Promise((resolve, reject) => {
157
181
  const req = protocol.request(url, {
158
- timeout,
182
+ timeout: connectTimeOut,
159
183
  headers: Object.assign(headers, Object.assign({}, form.getHeaders())),
160
184
  method: 'post',
161
185
  agent
162
186
  }, res => {
163
- resHandld(res, resolve, reject, resType, 'post');
187
+ resHandld(res, resolve, reject, resType, 'post', readTimeOut, req);
164
188
  });
165
189
  req.on('timeout', () => {
166
190
  req.destroy();
167
- reject(new Error(getTimeOutMessage(timeout)));
191
+ reject(buildTimeOutErr('connectTimeOut', connectTimeOut, url));
168
192
  });
169
193
  req.on('error', e => {
170
194
  req.destroy();
@@ -183,7 +207,7 @@ function reqSendMultiPart(url, options) {
183
207
  });
184
208
  }
185
209
  exports.reqSendMultiPart = reqSendMultiPart;
186
- function resHandld(res, resolve, reject, resType, method) {
210
+ function resHandld(res, resolve, reject, resType, method, readTimeOut, req) {
187
211
  const reqUrl = `${res.req.protocol}//${res.req.host}${res.req.path}`;
188
212
  const resHeaders = {};
189
213
  for (let i = 0; i < res.rawHeaders.length; i += 2) {
@@ -193,9 +217,12 @@ function resHandld(res, resolve, reject, resType, method) {
193
217
  }
194
218
  }
195
219
  if (res.statusCode >= 400) {
196
- errHandle(reject, res, reqUrl, resHeaders);
220
+ errHandle(reject, res, reqUrl, resHeaders, readTimeOut, req);
197
221
  return;
198
222
  }
223
+ successHandle(resolve, reject, res, resType, method, reqUrl, resHeaders, readTimeOut, req);
224
+ }
225
+ function successHandle(resolve, reject, res, resType, method, reqUrl, resHeaders, readTimeOut, req) {
199
226
  const resData = {
200
227
  reqUrl,
201
228
  resHeaders,
@@ -210,56 +237,112 @@ function resHandld(res, resolve, reject, resType, method) {
210
237
  resolve(resData);
211
238
  return;
212
239
  }
240
+ let isReadTimeOut = false;
241
+ let isReadFinished = false;
242
+ let readTimer;
213
243
  let resBody;
214
244
  const chunks = [];
245
+ res.once('data', () => {
246
+ readTimer = setTimeout(() => {
247
+ if (!isReadFinished) {
248
+ isReadTimeOut = true;
249
+ req.destroy();
250
+ reject(buildTimeOutErr('readTimeOut', readTimeOut, reqUrl));
251
+ }
252
+ }, readTimeOut);
253
+ });
215
254
  res.on('data', chunk => {
216
255
  chunks.push(chunk);
217
256
  });
218
257
  res.on('end', () => {
219
- const buffer = Buffer.concat(chunks);
220
- if (resType === 'buffer') {
221
- resBody = buffer;
222
- }
223
- else {
224
- const responseStr = buffer.toString();
225
- if (resType === 'text') {
226
- resBody = responseStr;
258
+ if (!isReadTimeOut) {
259
+ const buffer = Buffer.concat(chunks);
260
+ if (resType === 'buffer') {
261
+ resBody = buffer;
227
262
  }
228
263
  else {
229
- try {
230
- resBody = JSON.parse(responseStr);
231
- }
232
- catch (e) {
264
+ const responseStr = buffer.toString();
265
+ if (resType === 'text') {
233
266
  resBody = responseStr;
234
267
  }
268
+ else {
269
+ try {
270
+ resBody = JSON.parse(responseStr);
271
+ }
272
+ catch (e) {
273
+ resBody = responseStr;
274
+ }
275
+ }
235
276
  }
277
+ resData.resBody = resBody;
278
+ isReadFinished = true;
279
+ clearTimeout(readTimer);
280
+ resolve(resData);
236
281
  }
237
- resData.resBody = resBody;
238
- resolve(resData);
239
282
  });
240
283
  }
241
- function errHandle(reject, res, reqUrl, resHeaders) {
284
+ function errHandle(reject, res, reqUrl, resHeaders, readTimeOut, req) {
285
+ let isReadTimeOut = false;
286
+ let isReadFinished = false;
287
+ let readTimer;
242
288
  const chunks = [];
289
+ res.once('data', () => {
290
+ readTimer = setTimeout(() => {
291
+ if (!isReadFinished) {
292
+ isReadTimeOut = true;
293
+ req.destroy();
294
+ reject(buildTimeOutErr('readTimeOut', readTimeOut, reqUrl));
295
+ }
296
+ }, readTimeOut);
297
+ });
243
298
  res.on('data', chunk => {
244
299
  chunks.push(chunk);
245
300
  });
246
301
  res.on('end', () => {
247
- const buffer = Buffer.concat(chunks);
248
- const resData = buffer.toString();
249
- let resBody;
250
- try {
251
- resBody = JSON.parse(resData);
252
- }
253
- catch (e) {
254
- resBody = resData;
302
+ if (!isReadTimeOut) {
303
+ const buffer = Buffer.concat(chunks);
304
+ const resData = buffer.toString();
305
+ let resBody;
306
+ try {
307
+ resBody = JSON.parse(resData);
308
+ }
309
+ catch (e) {
310
+ resBody = resData;
311
+ }
312
+ const err = new Error();
313
+ err.code = res.statusCode;
314
+ err.name = 'statusCodeError';
315
+ err.message = `${res.statusCode}|${res.statusMessage}`;
316
+ err.resBody = resBody;
317
+ err.reqUrl = reqUrl;
318
+ err.resHeaders = resHeaders;
319
+ isReadFinished = true;
320
+ clearTimeout(readTimer);
321
+ reject(err);
255
322
  }
256
- const err = new Error();
257
- err.code = res.statusCode;
258
- err.name = 'statusCodeError';
259
- err.message = `${res.statusCode}|${res.statusMessage}`;
260
- err.resBody = resBody;
261
- err.reqUrl = reqUrl;
262
- err.resHeaders = resHeaders;
263
- reject(err);
264
323
  });
265
324
  }
325
+ function get(url, options) {
326
+ return __awaiter(this, void 0, void 0, function* () {
327
+ return request(url, Object.assign(Object.assign({}, options), { method: 'get' }));
328
+ });
329
+ }
330
+ exports.get = get;
331
+ function post(url, options) {
332
+ return __awaiter(this, void 0, void 0, function* () {
333
+ return request(url, Object.assign(Object.assign({}, options), { method: 'post' }));
334
+ });
335
+ }
336
+ exports.post = post;
337
+ function put(url, options) {
338
+ return __awaiter(this, void 0, void 0, function* () {
339
+ return request(url, Object.assign(Object.assign({}, options), { method: 'put' }));
340
+ });
341
+ }
342
+ exports.put = put;
343
+ function head(url, options) {
344
+ return __awaiter(this, void 0, void 0, function* () {
345
+ return request(url, Object.assign(Object.assign({}, options), { method: 'head' }));
346
+ });
347
+ }
348
+ exports.head = head;
package/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ReadStream, WriteStream } from 'fs';
2
+ import { Encoding } from 'crypto';
2
3
 
3
4
  import {
4
5
  reqOptions,
@@ -17,6 +18,30 @@ import {
17
18
  } from './src/cutil';
18
19
 
19
20
  interface Hgo {
21
+ /**
22
+ * request through get
23
+ * @param url
24
+ * @param options
25
+ */
26
+ get(url: string, options?: Omit<reqOptions, 'method'>): Promise<ResData>,
27
+ /**
28
+ * request through post
29
+ * @param url
30
+ * @param options
31
+ */
32
+ post(url: string, options?: Omit<reqOptions, 'method'>): Promise<ResData>,
33
+ /**
34
+ * request through put
35
+ * @param url
36
+ * @param options
37
+ */
38
+ put(url: string, options?: Omit<reqOptions, 'method'>): Promise<ResData>,
39
+ /**
40
+ * request through head
41
+ * @param url
42
+ * @param options
43
+ */
44
+ head(url: string, options?: Omit<reqOptions, 'method'>): Promise<ResData>,
20
45
  /**
21
46
  * 发出普通请求
22
47
  * @param url
@@ -66,6 +91,35 @@ interface Cutil {
66
91
  * @param options
67
92
  */
68
93
  randomString(length: number, options?: randomStringOptions): string
94
+ /**
95
+ * 以CBC算法进行对称加密
96
+ * @param data 待加密数据
97
+ * @param length 算法长度(秘钥需要按照这个长度输入)
98
+ * @param key 秘钥
99
+ * @param iv 偏移量(16字节)
100
+ * @param inputEncoding 输入编码(默认utf-8)
101
+ */
102
+ encryptCBC(data: string, length: 128 | 192 | 256, key: Buffer, iv: Buffer, inputEncoding?: Encoding): string
103
+ /**
104
+ * 以CBC算法进行对称解密
105
+ * @param encryptData 待解密数据
106
+ * @param length 算法长度(秘钥需要按照这个长度输入)
107
+ * @param key 秘钥
108
+ * @param iv 偏移量(16字节)
109
+ * @param outputEncoding 输出编码(默认utf-8)
110
+ */
111
+ decryptCBC(encryptData: string, length: 128 | 192 | 256, key: Buffer, iv: Buffer, outputEncoding?: Encoding): string
112
+ /**
113
+ * md5加密
114
+ * @param data 待加密数据
115
+ * @param inputEncoding 输入编码
116
+ */
117
+ md5(data: string, inputEncoding?: Encoding): string
118
+ /**
119
+ * 调用终端执行命令
120
+ * @param command
121
+ */
122
+ execCmdCommand(command: string): string
69
123
  }
70
124
 
71
125
  declare const hgo: Hgo;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cvitool",
3
- "version": "1.0.7",
3
+ "version": "1.0.71",
4
4
  "description": "cvitool",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/cutil.ts CHANGED
@@ -1,4 +1,13 @@
1
- import { randomInt } from 'crypto';
1
+ import {
2
+ randomInt,
3
+ createCipheriv,
4
+ createDecipheriv,
5
+ createHash,
6
+ Encoding
7
+ } from 'crypto';
8
+ import {
9
+ spawn
10
+ } from 'child_process';
2
11
 
3
12
  interface randomStringOptions {
4
13
  special?: boolean,
@@ -41,7 +50,54 @@ function randomString(length: number, options?: randomStringOptions) {
41
50
  return result;
42
51
  }
43
52
 
53
+ function encryptCBC(data: string, length: 128 | 192 | 256, key: Buffer, iv: Buffer, inputEncoding: Encoding = 'utf-8') {
54
+ const algorithm = `aes-${length}-cbc`;
55
+ const cipher = createCipheriv(algorithm, key, iv);
56
+ let crypted = cipher.update(data, inputEncoding, 'hex');
57
+ crypted += cipher.final('hex');
58
+ return crypted;
59
+ };
60
+
61
+ function decryptCBC(encryptData: string, length: 128 | 192 | 256, key: Buffer, iv: Buffer, outputEncoding: Encoding = 'utf-8') {
62
+ const algorithm = `aes-${length}-cbc`;
63
+ const decipher = createDecipheriv(algorithm, key, iv);
64
+ let decrypted = decipher.update(encryptData, 'hex', outputEncoding);
65
+ decrypted += decipher.final(outputEncoding);
66
+ return decrypted;
67
+ };
68
+
69
+ function md5(data: string, inputEncoding: Encoding = 'utf-8') {
70
+ return createHash('md5').update(data, inputEncoding).digest('hex');
71
+ }
72
+
73
+ async function execCmdCommand(command: string) {
74
+ const commandList = command.split(' ');
75
+ const commandName = commandList.splice(0, 1);
76
+ return new Promise((resolve, reject) => {
77
+ const chunks = [];
78
+ const cmd = spawn(commandName[0], commandList, { stdio: 'pipe', shell: true });
79
+ cmd.stdout.on('data', chunk => {
80
+ chunks.push(chunk);
81
+ });
82
+ cmd.stderr.on('data', chunk => {
83
+ chunks.push(chunk);
84
+ });
85
+ cmd.on('exit', (code) => {
86
+ const result = Buffer.concat(chunks).toString();
87
+ if (code !== 0) {
88
+ reject(result);
89
+ return;
90
+ }
91
+ resolve(result);
92
+ });
93
+ });
94
+ }
95
+
44
96
  export {
45
97
  randomStringOptions,
46
- randomString
98
+ randomString,
99
+ encryptCBC,
100
+ decryptCBC,
101
+ md5,
102
+ execCmdCommand
47
103
  };
package/src/hgo.ts CHANGED
@@ -12,15 +12,17 @@ interface CustomObject {
12
12
 
13
13
  interface baseReqOptions {
14
14
  timeout?: number,
15
- method?: Method,
16
15
  agent?: http.Agent | https.Agent,
17
16
  headers?: {
18
17
  [key: string]: string
19
18
  },
20
- resType?: ResType
19
+ resType?: ResType,
20
+ connectTimeOut?: number,
21
+ readTimeOut?: number,
21
22
  }
22
23
 
23
24
  interface reqOptions extends baseReqOptions {
25
+ method?: Method,
24
26
  query?: {
25
27
  [key: string]: string
26
28
  },
@@ -30,10 +32,12 @@ interface reqOptions extends baseReqOptions {
30
32
  }
31
33
 
32
34
  interface reqSendBufferOptions extends baseReqOptions {
35
+ method?: Method,
33
36
  buffer: Buffer
34
37
  }
35
38
 
36
39
  interface reqSendStreamOptions extends baseReqOptions {
40
+ method?: Method,
37
41
  stream: ReadStream
38
42
  }
39
43
 
@@ -47,8 +51,13 @@ interface ResData {
47
51
  resBody: http.IncomingMessage | CustomObject | string | Buffer | null
48
52
  }
49
53
 
50
- function getTimeOutMessage(timeout: number): string {
51
- return `request timeout of ${timeout} ms`;
54
+ function buildTimeOutErr(type: 'connectTimeOut' | 'readTimeOut', timeout: number, reqUrl?: string) {
55
+ const err: any = new Error();
56
+ err.code = 'TimeOut';
57
+ err.name = `${type}Error`;
58
+ err.message = `${type} for ${timeout} ms`;
59
+ err.reqUrl = reqUrl;
60
+ return err as Error;
52
61
  }
53
62
 
54
63
  function getProtocol(url: string) {
@@ -56,7 +65,11 @@ function getProtocol(url: string) {
56
65
  }
57
66
 
58
67
  async function request(url: string, options?: reqOptions): Promise<ResData> {
59
- const { query = {}, body = {}, headers = {}, timeout = 5000, method = 'get', agent, resType = 'json' } = options || {};
68
+ let { query = {}, body = {}, headers = {}, timeout = 5000, method = 'get', agent, resType = 'json', connectTimeOut, readTimeOut } = options || {};
69
+ if (timeout && !(connectTimeOut && readTimeOut)) {
70
+ connectTimeOut = timeout;
71
+ readTimeOut = timeout;
72
+ }
60
73
  if (Object.keys(query).length !== 0) {
61
74
  if (url.indexOf('?') > -1) {
62
75
  url = url + '&' + querystring.stringify(query);
@@ -67,22 +80,25 @@ async function request(url: string, options?: reqOptions): Promise<ResData> {
67
80
  const data = JSON.stringify(body);
68
81
  const protocol = getProtocol(url);
69
82
  const isbodyEmpty = Object.keys(body).length === 0;
70
- const baseHeaders = {
71
- 'Content-Type': 'application/json;charset=utf-8',
72
- 'Content-length': isbodyEmpty ? 0 : Buffer.byteLength(data)
73
- };
83
+ let baseHeaders: CustomObject = {};
84
+ if (!isbodyEmpty) {
85
+ baseHeaders = {
86
+ 'Content-Type': 'application/json; charset=utf-8',
87
+ 'Content-length': Buffer.byteLength(data)
88
+ };
89
+ }
74
90
  return new Promise((resolve, reject) => {
75
91
  const req = protocol.request(url, {
76
- timeout,
92
+ timeout: connectTimeOut,
77
93
  headers: Object.assign(headers, baseHeaders),
78
94
  method,
79
95
  agent
80
96
  }, res => {
81
- resHandld(res, resolve, reject, resType, method);
97
+ resHandld(res, resolve, reject, resType, method, readTimeOut, req);
82
98
  });
83
99
  req.on('timeout', () => {
84
100
  req.destroy();
85
- reject(new Error(getTimeOutMessage(timeout)));
101
+ reject(buildTimeOutErr('connectTimeOut', connectTimeOut, url));
86
102
  });
87
103
  req.on('error', e => {
88
104
  req.destroy();
@@ -103,20 +119,24 @@ async function request(url: string, options?: reqOptions): Promise<ResData> {
103
119
  }
104
120
 
105
121
  async function reqSendBuffer(url: string, options: reqSendBufferOptions): Promise<ResData> {
106
- const { timeout = 60000, headers = {}, buffer, method = 'post', agent, resType = 'json' } = options;
122
+ let { timeout = 5000, headers = {}, buffer, method = 'post', agent, resType = 'json', connectTimeOut, readTimeOut } = options;
123
+ if (timeout && !(connectTimeOut && readTimeOut)) {
124
+ connectTimeOut = timeout;
125
+ readTimeOut = timeout;
126
+ }
107
127
  const protocol = getProtocol(url);
108
128
  return new Promise((resolve, reject) => {
109
129
  const req = protocol.request(url, {
110
- timeout,
130
+ timeout: connectTimeOut,
111
131
  headers: Object.assign(headers, { 'Content-Length': buffer.byteLength }),
112
132
  method,
113
133
  agent
114
134
  }, res => {
115
- resHandld(res, resolve, reject, resType, method);
135
+ resHandld(res, resolve, reject, resType, method, readTimeOut, req);
116
136
  });
117
137
  req.on('timeout', () => {
118
138
  req.destroy();
119
- reject(new Error(getTimeOutMessage(timeout)));
139
+ reject(buildTimeOutErr('connectTimeOut', connectTimeOut, url));
120
140
  });
121
141
  req.on('error', e => {
122
142
  req.destroy();
@@ -133,7 +153,11 @@ async function reqSendBuffer(url: string, options: reqSendBufferOptions): Promis
133
153
  }
134
154
 
135
155
  async function reqSendStream(url: string, options: reqSendStreamOptions): Promise<ResData> {
136
- const { timeout = 60000, method = 'post', stream, headers = {}, agent, resType = 'json' } = options;
156
+ let { timeout = 5000, method = 'post', stream, headers = {}, agent, resType = 'json', connectTimeOut, readTimeOut } = options;
157
+ if (timeout && !(connectTimeOut && readTimeOut)) {
158
+ connectTimeOut = timeout;
159
+ readTimeOut = timeout;
160
+ }
137
161
  const protocol = getProtocol(url);
138
162
  return new Promise((resolve, reject) => {
139
163
  const baseHeaders = {
@@ -142,16 +166,16 @@ async function reqSendStream(url: string, options: reqSendStreamOptions): Promis
142
166
  Connection: 'keep-alive'
143
167
  };
144
168
  const req = protocol.request(url, {
145
- timeout,
169
+ timeout: connectTimeOut,
146
170
  headers: Object.assign(headers, baseHeaders),
147
171
  method,
148
172
  agent
149
173
  }, res => {
150
- resHandld(res, resolve, reject, resType, method);
174
+ resHandld(res, resolve, reject, resType, method, readTimeOut, req);
151
175
  });
152
176
  req.on('timeout', () => {
153
177
  req.destroy();
154
- reject(new Error(getTimeOutMessage(timeout)));
178
+ reject(buildTimeOutErr('connectTimeOut', connectTimeOut, url));
155
179
  });
156
180
  req.on('error', e => {
157
181
  req.destroy();
@@ -178,20 +202,24 @@ async function reqSendStream(url: string, options: reqSendStreamOptions): Promis
178
202
  }
179
203
 
180
204
  async function reqSendMultiPart(url: string, options: reqSendMultiPartOptions): Promise<ResData> {
181
- const { timeout = 60000, headers = {}, form, agent, resType = 'json' } = options;
205
+ let { timeout = 60000, headers = {}, form, agent, resType = 'json', connectTimeOut, readTimeOut } = options;
206
+ if (timeout && !(connectTimeOut && readTimeOut)) {
207
+ connectTimeOut = timeout;
208
+ readTimeOut = timeout;
209
+ }
182
210
  const protocol = getProtocol(url);
183
211
  return new Promise((resolve, reject) => {
184
212
  const req = protocol.request(url, {
185
- timeout,
213
+ timeout: connectTimeOut,
186
214
  headers: Object.assign(headers, { ...form.getHeaders() }),
187
215
  method: 'post',
188
216
  agent
189
217
  }, res => {
190
- resHandld(res, resolve, reject, resType, 'post');
218
+ resHandld(res, resolve, reject, resType, 'post', readTimeOut, req);
191
219
  });
192
220
  req.on('timeout', () => {
193
221
  req.destroy();
194
- reject(new Error(getTimeOutMessage(timeout)));
222
+ reject(buildTimeOutErr('connectTimeOut', connectTimeOut, url));
195
223
  });
196
224
  req.on('error', e => {
197
225
  req.destroy();
@@ -209,7 +237,7 @@ async function reqSendMultiPart(url: string, options: reqSendMultiPartOptions):
209
237
  });
210
238
  }
211
239
 
212
- function resHandld(res: http.IncomingMessage, resolve: any, reject: any, resType: ResType, method: Method) {
240
+ function resHandld(res: http.IncomingMessage, resolve: any, reject: any, resType: ResType, method: Method, readTimeOut: number, req: http.ClientRequest) {
213
241
  const reqUrl = `${(res as any).req.protocol}//${(res as any).req.host}${(res as any).req.path}`;
214
242
  const resHeaders: CustomObject = {};
215
243
  for (let i = 0; i < res.rawHeaders.length; i += 2) {
@@ -219,9 +247,13 @@ function resHandld(res: http.IncomingMessage, resolve: any, reject: any, resType
219
247
  }
220
248
  }
221
249
  if (res.statusCode >= 400) {
222
- errHandle(reject, res, reqUrl, resHeaders);
250
+ errHandle(reject, res, reqUrl, resHeaders, readTimeOut, req);
223
251
  return;
224
252
  }
253
+ successHandle(resolve, reject, res, resType, method, reqUrl, resHeaders, readTimeOut, req);
254
+ }
255
+
256
+ function successHandle(resolve: any, reject: any, res: http.IncomingMessage, resType: ResType, method: Method, reqUrl: string, resHeaders: CustomObject, readTimeOut: number, req: http.ClientRequest) {
225
257
  const resData = {
226
258
  reqUrl,
227
259
  resHeaders,
@@ -236,57 +268,105 @@ function resHandld(res: http.IncomingMessage, resolve: any, reject: any, resType
236
268
  resolve(resData);
237
269
  return;
238
270
  }
271
+ let isReadTimeOut = false;
272
+ let isReadFinished = false;
273
+ let readTimer: any;
239
274
  let resBody: Buffer | object | string;
240
275
  const chunks = [];
276
+ res.once('data', () => {
277
+ readTimer = setTimeout(() => {
278
+ if (!isReadFinished) {
279
+ isReadTimeOut = true;
280
+ req.destroy();
281
+ reject(buildTimeOutErr('readTimeOut', readTimeOut, reqUrl));
282
+ }
283
+ }, readTimeOut);
284
+ });
241
285
  res.on('data', chunk => {
242
286
  chunks.push(chunk);
243
287
  });
244
288
  res.on('end', () => {
245
- const buffer = Buffer.concat(chunks);
246
- if (resType === 'buffer') {
247
- resBody = buffer;
248
- } else {
249
- const responseStr = buffer.toString();
250
- if (resType === 'text') {
251
- resBody = responseStr;
289
+ if (!isReadTimeOut) {
290
+ const buffer = Buffer.concat(chunks);
291
+ if (resType === 'buffer') {
292
+ resBody = buffer;
252
293
  } else {
253
- try {
254
- resBody = JSON.parse(responseStr);
255
- } catch (e) {
294
+ const responseStr = buffer.toString();
295
+ if (resType === 'text') {
256
296
  resBody = responseStr;
297
+ } else {
298
+ try {
299
+ resBody = JSON.parse(responseStr);
300
+ } catch (e) {
301
+ resBody = responseStr;
302
+ }
257
303
  }
258
304
  }
305
+ resData.resBody = resBody;
306
+ isReadFinished = true;
307
+ clearTimeout(readTimer);
308
+ resolve(resData);
259
309
  }
260
- resData.resBody = resBody;
261
- resolve(resData);
262
310
  });
263
311
  }
264
312
 
265
- function errHandle(reject: any, res: http.IncomingMessage, reqUrl: string, resHeaders: CustomObject) {
313
+ function errHandle(reject: any, res: http.IncomingMessage, reqUrl: string, resHeaders: CustomObject, readTimeOut: number, req: http.ClientRequest) {
314
+ let isReadTimeOut = false;
315
+ let isReadFinished = false;
316
+ let readTimer: any;
266
317
  const chunks = [];
318
+ res.once('data', () => {
319
+ readTimer = setTimeout(() => {
320
+ if (!isReadFinished) {
321
+ isReadTimeOut = true;
322
+ req.destroy();
323
+ reject(buildTimeOutErr('readTimeOut', readTimeOut, reqUrl));
324
+ }
325
+ }, readTimeOut);
326
+ });
267
327
  res.on('data', chunk => {
268
328
  chunks.push(chunk);
269
329
  });
270
330
  res.on('end', () => {
271
- const buffer = Buffer.concat(chunks);
272
- const resData = buffer.toString();
273
- let resBody: object | string;
274
- try {
275
- resBody = JSON.parse(resData);
276
- } catch (e) {
277
- resBody = resData;
331
+ if (!isReadTimeOut) {
332
+ const buffer = Buffer.concat(chunks);
333
+ const resData = buffer.toString();
334
+ let resBody: object | string;
335
+ try {
336
+ resBody = JSON.parse(resData);
337
+ } catch (e) {
338
+ resBody = resData;
339
+ }
340
+ const err: any = new Error();
341
+ err.code = res.statusCode;
342
+ err.name = 'statusCodeError';
343
+ err.message = `${res.statusCode}|${res.statusMessage}`;
344
+ err.resBody = resBody;
345
+ err.reqUrl = reqUrl;
346
+ err.resHeaders = resHeaders;
347
+ isReadFinished = true;
348
+ clearTimeout(readTimer);
349
+ reject(err);
278
350
  }
279
- const err: any = new Error();
280
- err.code = res.statusCode;
281
- err.name = 'statusCodeError';
282
- err.message = `${res.statusCode}|${res.statusMessage}`;
283
- err.resBody = resBody;
284
- err.reqUrl = reqUrl;
285
- err.resHeaders = resHeaders;
286
- reject(err);
287
351
  });
288
352
  }
289
353
 
354
+ async function get(url: string, options?: Omit<reqOptions, 'method'>) {
355
+ return request(url, { ...options, method: 'get' });
356
+ }
357
+
358
+ async function post(url: string, options?: Omit<reqOptions, 'method'>) {
359
+ return request(url, { ...options, method: 'post' });
360
+ }
361
+
362
+ async function put(url: string, options?: Omit<reqOptions, 'method'>) {
363
+ return request(url, { ...options, method: 'put' });
364
+ }
365
+
366
+ async function head(url: string, options?: Omit<reqOptions, 'method'>) {
367
+ return request(url, { ...options, method: 'head' });
368
+ }
369
+
290
370
  export {
291
371
  reqOptions,
292
372
  reqSendBufferOptions,
@@ -297,4 +377,8 @@ export {
297
377
  reqSendBuffer,
298
378
  reqSendStream,
299
379
  reqSendMultiPart,
380
+ get,
381
+ post,
382
+ put,
383
+ head
300
384
  };