urllib 3.0.0-alpha.1 → 3.0.0
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.
- package/README.md +15 -113
- package/package.json +13 -9
- package/src/HttpAgent.ts +72 -0
- package/src/HttpClient.ts +303 -84
- package/src/Request.ts +51 -54
- package/src/Response.ts +11 -10
- package/src/cjs/HttpAgent.d.ts +16 -0
- package/src/cjs/HttpAgent.js +62 -0
- package/src/cjs/HttpAgent.js.map +1 -0
- package/src/cjs/HttpClient.d.ts +28 -1
- package/src/cjs/HttpClient.js +371 -198
- package/src/cjs/HttpClient.js.map +1 -1
- package/src/cjs/Request.d.ts +47 -54
- package/src/cjs/Response.d.ts +9 -8
- package/src/cjs/utils.d.ts +1 -0
- package/src/cjs/utils.js +7 -1
- package/src/cjs/utils.js.map +1 -1
- package/src/esm/HttpAgent.d.ts +16 -0
- package/src/esm/HttpAgent.js +58 -0
- package/src/esm/HttpAgent.js.map +1 -0
- package/src/esm/HttpClient.d.ts +28 -1
- package/src/esm/HttpClient.js +372 -199
- package/src/esm/HttpClient.js.map +1 -1
- package/src/esm/Request.d.ts +47 -54
- package/src/esm/Response.d.ts +9 -8
- package/src/esm/utils.d.ts +1 -0
- package/src/esm/utils.js +5 -0
- package/src/esm/utils.js.map +1 -1
- package/src/index.ts +0 -1
- package/src/utils.ts +6 -0
package/src/cjs/HttpClient.js
CHANGED
@@ -1,19 +1,46 @@
|
|
1
1
|
"use strict";
|
2
|
-
var
|
2
|
+
var _a, _b, _c;
|
3
|
+
var _BlobFromStream_stream, _BlobFromStream_type, _HttpClient_instances, _HttpClient_defaultArgs, _HttpClient_dispatcher, _HttpClient_requestInternal;
|
3
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
4
5
|
exports.HttpClient = void 0;
|
5
6
|
const tslib_1 = require("tslib");
|
6
7
|
const events_1 = require("events");
|
7
8
|
const util_1 = require("util");
|
8
|
-
const
|
9
|
-
const promises_1 = require("stream/promises");
|
9
|
+
const zlib_1 = require("zlib");
|
10
10
|
const buffer_1 = require("buffer");
|
11
|
-
const
|
11
|
+
const stream_1 = require("stream");
|
12
|
+
const stream_2 = tslib_1.__importDefault(require("stream"));
|
12
13
|
const path_1 = require("path");
|
14
|
+
const fs_1 = require("fs");
|
15
|
+
const perf_hooks_1 = require("perf_hooks");
|
13
16
|
const undici_1 = require("undici");
|
17
|
+
const formdata_node_1 = require("formdata-node");
|
18
|
+
const form_data_encoder_1 = require("form-data-encoder");
|
14
19
|
const default_user_agent_1 = tslib_1.__importDefault(require("default-user-agent"));
|
15
20
|
const mime_types_1 = tslib_1.__importDefault(require("mime-types"));
|
21
|
+
const pump_1 = tslib_1.__importDefault(require("pump"));
|
22
|
+
const HttpAgent_1 = require("./HttpAgent");
|
16
23
|
const utils_1 = require("./utils");
|
24
|
+
const FormData = undici_1.FormData !== null && undici_1.FormData !== void 0 ? undici_1.FormData : formdata_node_1.FormData;
|
25
|
+
// impl isReadable on Node.js 14
|
26
|
+
const isReadable = (_a = stream_2.default.isReadable) !== null && _a !== void 0 ? _a : function isReadable(stream) {
|
27
|
+
return stream && typeof stream.read === 'function';
|
28
|
+
};
|
29
|
+
// impl promise pipeline on Node.js 14
|
30
|
+
const pipelinePromise = (_c = (_b = stream_2.default.promises) === null || _b === void 0 ? void 0 : _b.pipeline) !== null && _c !== void 0 ? _c : function pipeline(...args) {
|
31
|
+
return new Promise((resolve, reject) => {
|
32
|
+
(0, pump_1.default)(...args, (err) => {
|
33
|
+
if (err)
|
34
|
+
return reject(err);
|
35
|
+
resolve();
|
36
|
+
});
|
37
|
+
});
|
38
|
+
};
|
39
|
+
function noop() {
|
40
|
+
// noop
|
41
|
+
}
|
42
|
+
const MAX_REQURE_ID_VALUE = Math.pow(2, 31) - 10;
|
43
|
+
let globalRequestId = 0;
|
17
44
|
const debug = (0, util_1.debuglog)('urllib');
|
18
45
|
// https://github.com/octet-stream/form-data
|
19
46
|
class BlobFromStream {
|
@@ -49,245 +76,391 @@ function getFileName(stream) {
|
|
49
76
|
}
|
50
77
|
return '';
|
51
78
|
}
|
79
|
+
function defaultIsRetry(response) {
|
80
|
+
return response.status >= 500;
|
81
|
+
}
|
82
|
+
function performanceTime(startTime) {
|
83
|
+
return Math.floor((perf_hooks_1.performance.now() - startTime) * 1000) / 1000;
|
84
|
+
}
|
52
85
|
class HttpClient extends events_1.EventEmitter {
|
53
86
|
constructor(clientOptions) {
|
54
87
|
super();
|
55
|
-
this
|
88
|
+
_HttpClient_instances.add(this);
|
89
|
+
_HttpClient_defaultArgs.set(this, void 0);
|
90
|
+
_HttpClient_dispatcher.set(this, void 0);
|
91
|
+
tslib_1.__classPrivateFieldSet(this, _HttpClient_defaultArgs, clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.defaultArgs, "f");
|
92
|
+
if ((clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.lookup) || (clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.checkAddress) || (clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.connect)) {
|
93
|
+
tslib_1.__classPrivateFieldSet(this, _HttpClient_dispatcher, new HttpAgent_1.HttpAgent({
|
94
|
+
lookup: clientOptions.lookup,
|
95
|
+
checkAddress: clientOptions.checkAddress,
|
96
|
+
connect: clientOptions.connect,
|
97
|
+
}), "f");
|
98
|
+
}
|
56
99
|
}
|
57
100
|
async request(url, options) {
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
101
|
+
return await tslib_1.__classPrivateFieldGet(this, _HttpClient_instances, "m", _HttpClient_requestInternal).call(this, url, options);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
exports.HttpClient = HttpClient;
|
105
|
+
_HttpClient_defaultArgs = new WeakMap(), _HttpClient_dispatcher = new WeakMap(), _HttpClient_instances = new WeakSet(), _HttpClient_requestInternal = async function _HttpClient_requestInternal(url, options, requestContext) {
|
106
|
+
var _a, _b, _c, _d, _e, _f;
|
107
|
+
if (globalRequestId >= MAX_REQURE_ID_VALUE) {
|
108
|
+
globalRequestId = 0;
|
109
|
+
}
|
110
|
+
const requestId = ++globalRequestId;
|
111
|
+
const requestUrl = typeof url === 'string' ? new URL(url) : url;
|
112
|
+
const args = {
|
113
|
+
retry: 0,
|
114
|
+
...tslib_1.__classPrivateFieldGet(this, _HttpClient_defaultArgs, "f"),
|
115
|
+
...options,
|
116
|
+
};
|
117
|
+
requestContext = {
|
118
|
+
retries: 0,
|
119
|
+
...requestContext,
|
120
|
+
};
|
121
|
+
const requestStartTime = perf_hooks_1.performance.now();
|
122
|
+
const reqMeta = {
|
123
|
+
requestId,
|
124
|
+
url: requestUrl.href,
|
125
|
+
args,
|
126
|
+
ctx: args.ctx,
|
127
|
+
};
|
128
|
+
// keep urllib createCallbackResponse style
|
129
|
+
const resHeaders = {};
|
130
|
+
const res = {
|
131
|
+
status: -1,
|
132
|
+
statusCode: -1,
|
133
|
+
headers: resHeaders,
|
134
|
+
size: 0,
|
135
|
+
aborted: false,
|
136
|
+
rt: 0,
|
137
|
+
keepAliveSocket: true,
|
138
|
+
requestUrls: [],
|
139
|
+
timing: {
|
140
|
+
waiting: 0,
|
141
|
+
contentDownload: 0,
|
142
|
+
},
|
143
|
+
};
|
144
|
+
let headersTimeout = 5000;
|
145
|
+
let bodyTimeout = 5000;
|
146
|
+
if (args.timeout) {
|
147
|
+
if (Array.isArray(args.timeout)) {
|
148
|
+
headersTimeout = (_a = args.timeout[0]) !== null && _a !== void 0 ? _a : headersTimeout;
|
149
|
+
bodyTimeout = (_b = args.timeout[1]) !== null && _b !== void 0 ? _b : bodyTimeout;
|
150
|
+
}
|
151
|
+
else {
|
152
|
+
headersTimeout = bodyTimeout = args.timeout;
|
153
|
+
}
|
154
|
+
}
|
155
|
+
const method = ((_c = args.method) !== null && _c !== void 0 ? _c : 'GET').toUpperCase();
|
156
|
+
const headers = {};
|
157
|
+
if (args.headers) {
|
158
|
+
// convert headers to lower-case
|
159
|
+
for (const name in args.headers) {
|
160
|
+
headers[name.toLowerCase()] = args.headers[name];
|
161
|
+
}
|
162
|
+
}
|
163
|
+
// hidden user-agent
|
164
|
+
const hiddenUserAgent = 'user-agent' in headers && !headers['user-agent'];
|
165
|
+
if (hiddenUserAgent) {
|
166
|
+
delete headers['user-agent'];
|
167
|
+
}
|
168
|
+
else if (!headers['user-agent']) {
|
169
|
+
// need to set user-agent
|
170
|
+
headers['user-agent'] = HEADER_USER_AGENT;
|
171
|
+
}
|
172
|
+
// Alias to dataType = 'stream'
|
173
|
+
if (args.streaming || args.customResponse) {
|
174
|
+
args.dataType = 'stream';
|
175
|
+
}
|
176
|
+
if (args.dataType === 'json' && !headers.accept) {
|
177
|
+
headers.accept = 'application/json';
|
178
|
+
}
|
179
|
+
// gzip alias to compressed
|
180
|
+
if (args.gzip && args.compressed !== false) {
|
181
|
+
args.compressed = true;
|
182
|
+
}
|
183
|
+
if (args.compressed && !headers['accept-encoding']) {
|
184
|
+
headers['accept-encoding'] = 'gzip, br';
|
185
|
+
}
|
186
|
+
if (requestContext.retries > 0) {
|
187
|
+
headers['x-urllib-retry'] = `${requestContext.retries}/${args.retry}`;
|
188
|
+
}
|
189
|
+
if (args.auth && !headers.authorization) {
|
190
|
+
headers.authorization = `Basic ${Buffer.from(args.auth).toString('base64')}`;
|
191
|
+
}
|
192
|
+
let opaque = args.opaque;
|
193
|
+
try {
|
194
|
+
const requestOptions = {
|
195
|
+
method,
|
196
|
+
keepalive: true,
|
197
|
+
maxRedirections: (_d = args.maxRedirects) !== null && _d !== void 0 ? _d : 10,
|
198
|
+
headersTimeout,
|
199
|
+
bodyTimeout,
|
200
|
+
opaque,
|
201
|
+
dispatcher: tslib_1.__classPrivateFieldGet(this, _HttpClient_dispatcher, "f"),
|
81
202
|
};
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
}
|
203
|
+
if (args.followRedirect === false) {
|
204
|
+
requestOptions.maxRedirections = 0;
|
205
|
+
}
|
206
|
+
const isGETOrHEAD = requestOptions.method === 'GET' || requestOptions.method === 'HEAD';
|
207
|
+
// alias to args.content
|
208
|
+
if (args.stream && !args.content) {
|
209
|
+
args.content = args.stream;
|
90
210
|
}
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
try {
|
95
|
-
const headers = new undici_1.Headers((_c = args.headers) !== null && _c !== void 0 ? _c : {});
|
96
|
-
if (!headers.has('user-agent')) {
|
97
|
-
// need to set user-agent
|
98
|
-
headers.set('user-agent', HEADER_USER_AGENT);
|
211
|
+
if (args.files) {
|
212
|
+
if (isGETOrHEAD) {
|
213
|
+
requestOptions.method = 'POST';
|
99
214
|
}
|
100
|
-
|
101
|
-
|
215
|
+
const formData = new FormData();
|
216
|
+
const uploadFiles = [];
|
217
|
+
if (Array.isArray(args.files)) {
|
218
|
+
for (const [index, file] of args.files.entries()) {
|
219
|
+
const field = index === 0 ? 'file' : `file${index}`;
|
220
|
+
uploadFiles.push([field, file]);
|
221
|
+
}
|
102
222
|
}
|
103
|
-
|
104
|
-
|
105
|
-
keepalive: true,
|
106
|
-
signal: requestTimeoutController.signal,
|
107
|
-
};
|
108
|
-
if (args.followRedirect === false) {
|
109
|
-
requestOptions.redirect = 'manual';
|
223
|
+
else if (args.files instanceof stream_1.Readable || isReadable(args.files)) {
|
224
|
+
uploadFiles.push(['file', args.files]);
|
110
225
|
}
|
111
|
-
|
112
|
-
|
113
|
-
if (args.stream && !args.content) {
|
114
|
-
args.content = args.stream;
|
226
|
+
else if (typeof args.files === 'string' || Buffer.isBuffer(args.files)) {
|
227
|
+
uploadFiles.push(['file', args.files]);
|
115
228
|
}
|
116
|
-
if (args.files) {
|
117
|
-
|
118
|
-
|
229
|
+
else if (typeof args.files === 'object') {
|
230
|
+
for (const field in args.files) {
|
231
|
+
uploadFiles.push([field, args.files[field]]);
|
119
232
|
}
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
uploadFiles.push([field, file]);
|
126
|
-
}
|
233
|
+
}
|
234
|
+
// set normal fields first
|
235
|
+
if (args.data) {
|
236
|
+
for (const field in args.data) {
|
237
|
+
formData.append(field, args.data[field]);
|
127
238
|
}
|
128
|
-
|
129
|
-
|
239
|
+
}
|
240
|
+
for (const [index, [field, file]] of uploadFiles.entries()) {
|
241
|
+
if (typeof file === 'string') {
|
242
|
+
// FIXME: support non-ascii filename
|
243
|
+
// const fileName = encodeURIComponent(basename(file));
|
244
|
+
// formData.append(field, await fileFromPath(file, `utf-8''${fileName}`, { type: mime.lookup(fileName) || '' }));
|
245
|
+
const fileName = (0, path_1.basename)(file);
|
246
|
+
const fileReadable = (0, fs_1.createReadStream)(file);
|
247
|
+
formData.append(field, new BlobFromStream(fileReadable, mime_types_1.default.lookup(fileName) || ''), fileName);
|
130
248
|
}
|
131
|
-
else if (
|
132
|
-
|
249
|
+
else if (Buffer.isBuffer(file)) {
|
250
|
+
formData.append(field, new buffer_1.Blob([file]), `bufferfile${index}`);
|
133
251
|
}
|
134
|
-
else if (
|
135
|
-
|
136
|
-
|
137
|
-
}
|
252
|
+
else if (file instanceof stream_1.Readable || isReadable(file)) {
|
253
|
+
const fileName = getFileName(file) || `streamfile${index}`;
|
254
|
+
formData.append(field, new BlobFromStream(file, mime_types_1.default.lookup(fileName) || ''), fileName);
|
138
255
|
}
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
256
|
+
}
|
257
|
+
if (undici_1.FormData) {
|
258
|
+
requestOptions.body = formData;
|
259
|
+
}
|
260
|
+
else {
|
261
|
+
// Node.js 14 does not support spec-compliant FormData
|
262
|
+
// https://github.com/octet-stream/form-data#usage
|
263
|
+
const encoder = new form_data_encoder_1.FormDataEncoder(formData);
|
264
|
+
Object.assign(headers, encoder.headers);
|
265
|
+
// fix "Content-Length":"NaN"
|
266
|
+
delete headers['Content-Length'];
|
267
|
+
requestOptions.body = stream_1.Readable.from(encoder);
|
268
|
+
}
|
269
|
+
}
|
270
|
+
else if (args.content) {
|
271
|
+
if (!isGETOrHEAD) {
|
272
|
+
// handle content
|
273
|
+
requestOptions.body = args.content;
|
274
|
+
if (args.contentType) {
|
275
|
+
headers['content-type'] = args.contentType;
|
144
276
|
}
|
145
|
-
|
146
|
-
|
147
|
-
// FIXME: support non-ascii filename
|
148
|
-
// const fileName = encodeURIComponent(basename(file));
|
149
|
-
// formData.append(field, await fileFromPath(file, `utf-8''${fileName}`, { type: mime.lookup(fileName) || '' }));
|
150
|
-
const fileName = (0, path_1.basename)(file);
|
151
|
-
const fileReader = (0, fs_1.createReadStream)(file);
|
152
|
-
formData.append(field, new BlobFromStream(fileReader, mime_types_1.default.lookup(fileName) || ''), fileName);
|
153
|
-
}
|
154
|
-
else if (Buffer.isBuffer(file)) {
|
155
|
-
formData.append(field, new buffer_1.Blob([file]), `bufferfile${index}`);
|
156
|
-
}
|
157
|
-
else if (file instanceof stream_1.Readable || (0, stream_1.isReadable)(file)) {
|
158
|
-
const fileName = getFileName(file) || `streamfile${index}`;
|
159
|
-
formData.append(field, new BlobFromStream(file, mime_types_1.default.lookup(fileName) || ''), fileName);
|
160
|
-
}
|
277
|
+
if (typeof args.content === 'string' && !headers['content-type']) {
|
278
|
+
headers['content-type'] = 'text/plain;charset=UTF-8';
|
161
279
|
}
|
162
|
-
requestOptions.body = formData;
|
163
280
|
}
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
headers.set('content-type', args.contentType);
|
281
|
+
}
|
282
|
+
else if (args.data) {
|
283
|
+
const isStringOrBufferOrReadable = typeof args.data === 'string'
|
284
|
+
|| Buffer.isBuffer(args.data)
|
285
|
+
|| isReadable(args.data);
|
286
|
+
if (isGETOrHEAD) {
|
287
|
+
if (!isStringOrBufferOrReadable) {
|
288
|
+
for (const field in args.data) {
|
289
|
+
requestUrl.searchParams.append(field, args.data[field]);
|
174
290
|
}
|
175
291
|
}
|
176
292
|
}
|
177
|
-
else
|
178
|
-
|
179
|
-
|
180
|
-
|| (0, stream_1.isReadable)(args.data);
|
181
|
-
if (isGETOrHEAD) {
|
182
|
-
if (!isStringOrBufferOrReadable) {
|
183
|
-
for (const field in args.data) {
|
184
|
-
requestUrl.searchParams.append(field, args.data[field]);
|
185
|
-
}
|
186
|
-
}
|
293
|
+
else {
|
294
|
+
if (isStringOrBufferOrReadable) {
|
295
|
+
requestOptions.body = args.data;
|
187
296
|
}
|
188
297
|
else {
|
189
|
-
if (
|
190
|
-
|
191
|
-
|
192
|
-
|
298
|
+
if (args.contentType === 'json'
|
299
|
+
|| args.contentType === 'application/json'
|
300
|
+
|| ((_e = headers['content-type']) === null || _e === void 0 ? void 0 : _e.startsWith('application/json'))) {
|
301
|
+
requestOptions.body = JSON.stringify(args.data);
|
302
|
+
if (!headers['content-type']) {
|
303
|
+
headers['content-type'] = 'application/json';
|
193
304
|
}
|
194
|
-
requestOptions.body = args.data;
|
195
305
|
}
|
196
306
|
else {
|
197
|
-
|
198
|
-
|
199
|
-
|| ((_d = headers.get('content-type')) === null || _d === void 0 ? void 0 : _d.startsWith('application/json'))) {
|
200
|
-
requestOptions.body = JSON.stringify(args.data);
|
201
|
-
if (!headers.has('content-type')) {
|
202
|
-
headers.set('content-type', 'application/json');
|
203
|
-
}
|
204
|
-
}
|
205
|
-
else {
|
206
|
-
requestOptions.body = new URLSearchParams(args.data);
|
207
|
-
}
|
307
|
+
headers['content-type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
|
308
|
+
requestOptions.body = new URLSearchParams(args.data).toString();
|
208
309
|
}
|
209
310
|
}
|
210
311
|
}
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
312
|
+
}
|
313
|
+
debug('Request#%d %s %s, headers: %j, headersTimeout: %s, bodyTimeout: %s', requestId, requestOptions.method, requestUrl.href, headers, headersTimeout, bodyTimeout);
|
314
|
+
requestOptions.headers = headers;
|
315
|
+
if (this.listenerCount('request') > 0) {
|
316
|
+
this.emit('request', reqMeta);
|
317
|
+
}
|
318
|
+
const response = await (0, undici_1.request)(requestUrl, requestOptions);
|
319
|
+
opaque = response.opaque;
|
320
|
+
if (args.timing) {
|
321
|
+
res.timing.waiting = performanceTime(requestStartTime);
|
322
|
+
}
|
323
|
+
const context = response.context;
|
324
|
+
let lastUrl = '';
|
325
|
+
if (context === null || context === void 0 ? void 0 : context.history) {
|
326
|
+
for (const urlObject of context === null || context === void 0 ? void 0 : context.history) {
|
327
|
+
res.requestUrls.push(urlObject.href);
|
328
|
+
lastUrl = urlObject.href;
|
216
329
|
}
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
330
|
+
}
|
331
|
+
else {
|
332
|
+
res.requestUrls.push(requestUrl.href);
|
333
|
+
lastUrl = requestUrl.href;
|
334
|
+
}
|
335
|
+
const contentEncoding = response.headers['content-encoding'];
|
336
|
+
const isCompressedContent = contentEncoding === 'gzip' || contentEncoding === 'br';
|
337
|
+
res.headers = response.headers;
|
338
|
+
res.status = res.statusCode = response.statusCode;
|
339
|
+
if (res.headers['content-length']) {
|
340
|
+
res.size = parseInt(res.headers['content-length']);
|
341
|
+
}
|
342
|
+
let data = null;
|
343
|
+
let responseBodyStream;
|
344
|
+
if (args.dataType === 'stream') {
|
345
|
+
// streaming mode will disable retry
|
346
|
+
args.retry = 0;
|
347
|
+
const meta = {
|
348
|
+
status: res.status,
|
349
|
+
statusCode: res.statusCode,
|
350
|
+
headers: res.headers,
|
351
|
+
};
|
352
|
+
if (isCompressedContent) {
|
353
|
+
// gzip or br
|
354
|
+
const decoder = contentEncoding === 'gzip' ? (0, zlib_1.createGunzip)() : (0, zlib_1.createBrotliDecompress)();
|
355
|
+
responseBodyStream = Object.assign((0, stream_1.pipeline)(response.body, decoder, noop), meta);
|
221
356
|
}
|
222
|
-
|
223
|
-
|
357
|
+
else {
|
358
|
+
responseBodyStream = Object.assign(response.body, meta);
|
359
|
+
}
|
360
|
+
}
|
361
|
+
else if (args.writeStream) {
|
362
|
+
// streaming mode will disable retry
|
363
|
+
args.retry = 0;
|
364
|
+
if (isCompressedContent) {
|
365
|
+
const decoder = contentEncoding === 'gzip' ? (0, zlib_1.createGunzip)() : (0, zlib_1.createBrotliDecompress)();
|
366
|
+
await pipelinePromise(response.body, decoder, args.writeStream);
|
367
|
+
}
|
368
|
+
else {
|
369
|
+
await pipelinePromise(response.body, args.writeStream);
|
224
370
|
}
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
headers: res.headers,
|
233
|
-
};
|
234
|
-
if (typeof stream_1.Readable.fromWeb === 'function') {
|
235
|
-
responseBodyStream = Object.assign(stream_1.Readable.fromWeb(response.body), meta);
|
371
|
+
}
|
372
|
+
else {
|
373
|
+
// buffer
|
374
|
+
data = Buffer.from(await response.body.arrayBuffer());
|
375
|
+
if (isCompressedContent) {
|
376
|
+
try {
|
377
|
+
data = contentEncoding === 'gzip' ? (0, zlib_1.gunzipSync)(data) : (0, zlib_1.brotliDecompressSync)(data);
|
236
378
|
}
|
237
|
-
|
238
|
-
|
379
|
+
catch (err) {
|
380
|
+
if (err.name === 'Error') {
|
381
|
+
err.name = 'UnzipError';
|
382
|
+
}
|
383
|
+
throw err;
|
239
384
|
}
|
240
385
|
}
|
241
|
-
|
242
|
-
|
243
|
-
}
|
244
|
-
else if (args.dataType === 'text') {
|
245
|
-
data = await response.text();
|
386
|
+
if (args.dataType === 'text') {
|
387
|
+
data = data.toString();
|
246
388
|
}
|
247
389
|
else if (args.dataType === 'json') {
|
248
|
-
if (
|
249
|
-
data =
|
390
|
+
if (data.length === 0) {
|
391
|
+
data = null;
|
250
392
|
}
|
251
393
|
else {
|
252
|
-
data =
|
253
|
-
if (data.length === 0) {
|
254
|
-
data = null;
|
255
|
-
}
|
256
|
-
else {
|
257
|
-
data = (0, utils_1.parseJSON)(data, args.fixJSONCtlChars);
|
258
|
-
}
|
394
|
+
data = (0, utils_1.parseJSON)(data.toString(), args.fixJSONCtlChars);
|
259
395
|
}
|
260
396
|
}
|
261
|
-
else {
|
262
|
-
// buffer
|
263
|
-
data = Buffer.from(await response.arrayBuffer());
|
264
|
-
}
|
265
|
-
res.rt = res.timing.contentDownload = Date.now() - requestStartTime;
|
266
|
-
const clientResponse = {
|
267
|
-
status: res.status,
|
268
|
-
data,
|
269
|
-
headers: res.headers,
|
270
|
-
url: response.url,
|
271
|
-
redirected: response.redirected,
|
272
|
-
res: responseBodyStream !== null && responseBodyStream !== void 0 ? responseBodyStream : res,
|
273
|
-
};
|
274
|
-
return clientResponse;
|
275
397
|
}
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
398
|
+
res.rt = performanceTime(requestStartTime);
|
399
|
+
if (args.timing) {
|
400
|
+
res.timing.contentDownload = res.rt;
|
401
|
+
}
|
402
|
+
const clientResponse = {
|
403
|
+
opaque,
|
404
|
+
data,
|
405
|
+
status: res.status,
|
406
|
+
headers: res.headers,
|
407
|
+
url: lastUrl,
|
408
|
+
redirected: res.requestUrls.length > 1,
|
409
|
+
requestUrls: res.requestUrls,
|
410
|
+
res: responseBodyStream !== null && responseBodyStream !== void 0 ? responseBodyStream : res,
|
411
|
+
};
|
412
|
+
if (args.retry > 0 && requestContext.retries < args.retry) {
|
413
|
+
const isRetry = (_f = args.isRetry) !== null && _f !== void 0 ? _f : defaultIsRetry;
|
414
|
+
if (isRetry(clientResponse)) {
|
415
|
+
if (args.retryDelay) {
|
416
|
+
await (0, utils_1.sleep)(args.retryDelay);
|
417
|
+
}
|
418
|
+
requestContext.retries++;
|
419
|
+
return await tslib_1.__classPrivateFieldGet(this, _HttpClient_instances, "m", _HttpClient_requestInternal).call(this, url, options, requestContext);
|
280
420
|
}
|
281
|
-
err.res = res;
|
282
|
-
err.status = res.status;
|
283
|
-
err.headers = res.headers;
|
284
|
-
// console.error(err);
|
285
|
-
throw err;
|
286
421
|
}
|
287
|
-
|
288
|
-
|
422
|
+
if (this.listenerCount('response') > 0) {
|
423
|
+
this.emit('response', {
|
424
|
+
requestId,
|
425
|
+
error: null,
|
426
|
+
ctx: args.ctx,
|
427
|
+
req: reqMeta,
|
428
|
+
res,
|
429
|
+
});
|
289
430
|
}
|
431
|
+
return clientResponse;
|
290
432
|
}
|
291
|
-
|
292
|
-
|
433
|
+
catch (e) {
|
434
|
+
debug('Request#%d throw error: %s', requestId, e);
|
435
|
+
let err = e;
|
436
|
+
if (err.name === 'HeadersTimeoutError') {
|
437
|
+
err = new HttpClientRequestTimeoutError(headersTimeout, { cause: e });
|
438
|
+
}
|
439
|
+
else if (err.name === 'BodyTimeoutError') {
|
440
|
+
err = new HttpClientRequestTimeoutError(bodyTimeout, { cause: e });
|
441
|
+
}
|
442
|
+
err.opaque = opaque;
|
443
|
+
err.status = res.status;
|
444
|
+
err.headers = res.headers;
|
445
|
+
err.res = res;
|
446
|
+
// make sure requestUrls not empty
|
447
|
+
if (res.requestUrls.length === 0) {
|
448
|
+
res.requestUrls.push(requestUrl.href);
|
449
|
+
}
|
450
|
+
res.rt = performanceTime(requestStartTime);
|
451
|
+
if (args.timing) {
|
452
|
+
res.timing.contentDownload = res.rt;
|
453
|
+
}
|
454
|
+
if (this.listenerCount('response') > 0) {
|
455
|
+
this.emit('response', {
|
456
|
+
requestId,
|
457
|
+
error: err,
|
458
|
+
ctx: args.ctx,
|
459
|
+
req: reqMeta,
|
460
|
+
res,
|
461
|
+
});
|
462
|
+
}
|
463
|
+
throw err;
|
464
|
+
}
|
465
|
+
};
|
293
466
|
//# sourceMappingURL=HttpClient.js.map
|