@aws-sdk/xhr-http-handler 3.178.0 → 3.183.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/CHANGELOG.md +8 -0
- package/dist-es/request-timeout.js +9 -12
- package/dist-es/xhr-http-handler.js +122 -158
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [3.183.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.182.0...v3.183.0) (2022-10-03)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @aws-sdk/xhr-http-handler
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
# [3.178.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.177.0...v3.178.0) (2022-09-23)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @aws-sdk/xhr-http-handler
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
export
|
|
2
|
-
if (timeoutInMs
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
};
|
|
1
|
+
export const requestTimeout = (timeoutInMs = 0) => new Promise((resolve, reject) => {
|
|
2
|
+
if (timeoutInMs) {
|
|
3
|
+
setTimeout(() => {
|
|
4
|
+
const timeoutError = new Error(`Request did not complete within ${timeoutInMs} ms`);
|
|
5
|
+
timeoutError.name = "TimeoutError";
|
|
6
|
+
reject(timeoutError);
|
|
7
|
+
}, timeoutInMs);
|
|
8
|
+
}
|
|
9
|
+
});
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { __awaiter, __extends, __generator, __read, __values } from "tslib";
|
|
2
1
|
import { HttpResponse } from "@aws-sdk/protocol-http";
|
|
3
2
|
import { buildQueryString } from "@aws-sdk/querystring-builder";
|
|
4
3
|
import { EventEmitter } from "events";
|
|
5
4
|
import { requestTimeout } from "./request-timeout";
|
|
6
|
-
|
|
5
|
+
const EVENTS = {
|
|
7
6
|
get PROGRESS() {
|
|
8
7
|
return "xhr.progress";
|
|
9
8
|
},
|
|
@@ -17,179 +16,144 @@ var EVENTS = {
|
|
|
17
16
|
return "before.xhr.send";
|
|
18
17
|
},
|
|
19
18
|
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var _this = _super.call(this) || this;
|
|
19
|
+
export class XhrHttpHandler extends EventEmitter {
|
|
20
|
+
constructor(options) {
|
|
21
|
+
super();
|
|
24
22
|
if (typeof options === "function") {
|
|
25
|
-
|
|
23
|
+
this.configProvider = options();
|
|
26
24
|
}
|
|
27
25
|
else {
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
this.config = options ?? {};
|
|
27
|
+
this.configProvider = Promise.resolve(this.config);
|
|
30
28
|
}
|
|
31
|
-
return _this;
|
|
32
29
|
}
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
30
|
+
destroy() {
|
|
31
|
+
}
|
|
32
|
+
async handle(request, { abortSignal } = {}) {
|
|
33
|
+
if (!this.config) {
|
|
34
|
+
this.config = await this.configProvider;
|
|
35
|
+
}
|
|
36
|
+
const requestTimeoutInMs = Number(this.config.requestTimeout) | 0;
|
|
37
|
+
if (abortSignal?.aborted) {
|
|
38
|
+
const abortError = new Error("Request aborted");
|
|
39
|
+
abortError.name = "AbortError";
|
|
40
|
+
throw abortError;
|
|
41
|
+
}
|
|
42
|
+
let path = request.path;
|
|
43
|
+
if (request.query) {
|
|
44
|
+
const queryString = buildQueryString(request.query);
|
|
45
|
+
if (queryString) {
|
|
46
|
+
path += `?${queryString}`;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const { port, method } = request;
|
|
50
|
+
const url = `${request.protocol}//${request.hostname}${port ? `:${port}` : ""}${path}`;
|
|
51
|
+
const body = method === "GET" || method === "HEAD" ? undefined : request.body;
|
|
52
|
+
const xhr = new XMLHttpRequest();
|
|
53
|
+
this.emit(EVENTS.XHR_INSTANTIATED, xhr);
|
|
54
|
+
const raceOfPromises = [
|
|
55
|
+
new Promise((resolve, reject) => {
|
|
56
|
+
let streamCursor = 0;
|
|
57
|
+
let stream;
|
|
58
|
+
let writer;
|
|
59
|
+
xhr.upload.addEventListener("progress", (event) => {
|
|
60
|
+
this.emit(XhrHttpHandler.EVENTS.UPLOAD_PROGRESS, event, request);
|
|
61
|
+
});
|
|
62
|
+
xhr.addEventListener("progress", (event) => {
|
|
63
|
+
this.emit(XhrHttpHandler.EVENTS.PROGRESS, event, request);
|
|
64
|
+
});
|
|
65
|
+
xhr.addEventListener("error", reject);
|
|
66
|
+
xhr.addEventListener("timeout", () => {
|
|
67
|
+
reject(new Error("XMLHttpRequest timed out."));
|
|
68
|
+
});
|
|
69
|
+
xhr.addEventListener("readystatechange", () => {
|
|
70
|
+
const isArrayBuffer = xhr.responseType === "arraybuffer" && xhr.response;
|
|
71
|
+
const isText = !isArrayBuffer && typeof xhr.responseText === "string";
|
|
72
|
+
if (isText && !stream) {
|
|
73
|
+
({ stream, writer } = this.initializeTransformStream());
|
|
74
|
+
}
|
|
75
|
+
switch (xhr.readyState) {
|
|
76
|
+
case XMLHttpRequest.LOADING:
|
|
77
|
+
if (isText) {
|
|
78
|
+
writer.write(streamCursor > 0 ? xhr.responseText.slice(streamCursor) : xhr.responseText);
|
|
79
|
+
streamCursor = xhr.responseText.length;
|
|
61
80
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
this.emit(EVENTS.XHR_INSTANTIATED, xhr);
|
|
68
|
-
raceOfPromises = [
|
|
69
|
-
new Promise(function (resolve, reject) {
|
|
70
|
-
var e_1, _a;
|
|
71
|
-
var streamCursor = 0;
|
|
72
|
-
var stream;
|
|
73
|
-
var writer;
|
|
74
|
-
xhr.upload.addEventListener("progress", function (event) {
|
|
75
|
-
_this.emit(XhrHttpHandler.EVENTS.UPLOAD_PROGRESS, event, request);
|
|
76
|
-
});
|
|
77
|
-
xhr.addEventListener("progress", function (event) {
|
|
78
|
-
_this.emit(XhrHttpHandler.EVENTS.PROGRESS, event, request);
|
|
79
|
-
});
|
|
80
|
-
xhr.addEventListener("error", reject);
|
|
81
|
-
xhr.addEventListener("timeout", function () {
|
|
82
|
-
reject(new Error("XMLHttpRequest timed out."));
|
|
83
|
-
});
|
|
84
|
-
xhr.addEventListener("readystatechange", function () {
|
|
85
|
-
var _a;
|
|
86
|
-
var isArrayBuffer = xhr.responseType === "arraybuffer" && xhr.response;
|
|
87
|
-
var isText = !isArrayBuffer && typeof xhr.responseText === "string";
|
|
88
|
-
if (isText && !stream) {
|
|
89
|
-
(_a = _this.initializeTransformStream(), stream = _a.stream, writer = _a.writer);
|
|
90
|
-
}
|
|
91
|
-
switch (xhr.readyState) {
|
|
92
|
-
case XMLHttpRequest.LOADING:
|
|
93
|
-
if (isText) {
|
|
94
|
-
writer.write(streamCursor > 0 ? xhr.responseText.slice(streamCursor) : xhr.responseText);
|
|
95
|
-
streamCursor = xhr.responseText.length;
|
|
96
|
-
}
|
|
97
|
-
break;
|
|
98
|
-
case XMLHttpRequest.DONE:
|
|
99
|
-
var body_1 = (function () {
|
|
100
|
-
if (isArrayBuffer) {
|
|
101
|
-
return new Blob([xhr.response]);
|
|
102
|
-
}
|
|
103
|
-
if (isText) {
|
|
104
|
-
writer.releaseLock();
|
|
105
|
-
stream.writable.close();
|
|
106
|
-
return stream.readable;
|
|
107
|
-
}
|
|
108
|
-
reject(new Error("Unexpected XHR response type ".concat(xhr.responseType, ". Expected string or arraybuffer.")));
|
|
109
|
-
})();
|
|
110
|
-
resolve({
|
|
111
|
-
response: new HttpResponse({
|
|
112
|
-
headers: _this.responseHeaders(xhr.getAllResponseHeaders()),
|
|
113
|
-
statusCode: xhr.status,
|
|
114
|
-
body: body_1,
|
|
115
|
-
}),
|
|
116
|
-
});
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
xhr.open(method, url);
|
|
121
|
-
try {
|
|
122
|
-
for (var _b = __values(Object.entries(request.headers)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
123
|
-
var _d = __read(_c.value, 2), header = _d[0], value = _d[1];
|
|
124
|
-
if (!isForbiddenRequestHeader(header)) {
|
|
125
|
-
xhr.setRequestHeader(header, value);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
81
|
+
break;
|
|
82
|
+
case XMLHttpRequest.DONE:
|
|
83
|
+
const body = (() => {
|
|
84
|
+
if (isArrayBuffer) {
|
|
85
|
+
return new Blob([xhr.response]);
|
|
128
86
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
finally { if (e_1) throw e_1.error; }
|
|
87
|
+
if (isText) {
|
|
88
|
+
writer.releaseLock();
|
|
89
|
+
stream.writable.close();
|
|
90
|
+
return stream.readable;
|
|
135
91
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
92
|
+
reject(new Error(`Unexpected XHR response type ${xhr.responseType}. Expected string or arraybuffer.`));
|
|
93
|
+
})();
|
|
94
|
+
resolve({
|
|
95
|
+
response: new HttpResponse({
|
|
96
|
+
headers: this.responseHeaders(xhr.getAllResponseHeaders()),
|
|
97
|
+
statusCode: xhr.status,
|
|
98
|
+
body,
|
|
99
|
+
}),
|
|
100
|
+
});
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
xhr.open(method, url);
|
|
105
|
+
for (const [header, value] of Object.entries(request.headers)) {
|
|
106
|
+
if (!isForbiddenRequestHeader(header)) {
|
|
107
|
+
xhr.setRequestHeader(header, value);
|
|
108
|
+
}
|
|
152
109
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
110
|
+
this.emit(EVENTS.BEFORE_XHR_SEND, xhr);
|
|
111
|
+
xhr.send(body);
|
|
112
|
+
}),
|
|
113
|
+
requestTimeout(requestTimeoutInMs),
|
|
114
|
+
];
|
|
115
|
+
if (abortSignal) {
|
|
116
|
+
raceOfPromises.push(new Promise((resolve, reject) => {
|
|
117
|
+
abortSignal.onabort = () => {
|
|
118
|
+
xhr.abort();
|
|
119
|
+
const abortError = new Error("Request aborted");
|
|
120
|
+
abortError.name = "AbortError";
|
|
121
|
+
reject(abortError);
|
|
122
|
+
};
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
return Promise.race(raceOfPromises);
|
|
126
|
+
}
|
|
127
|
+
responseHeaders(xhrHeaders) {
|
|
157
128
|
if (!xhrHeaders) {
|
|
158
129
|
return {};
|
|
159
130
|
}
|
|
160
|
-
return xhrHeaders.split("\r\n").reduce(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
131
|
+
return xhrHeaders.split("\r\n").reduce((headerMap, line) => {
|
|
132
|
+
const parts = line.split(": ");
|
|
133
|
+
const header = parts.shift();
|
|
134
|
+
const value = parts.join(": ");
|
|
164
135
|
headerMap[header] = value;
|
|
165
136
|
return headerMap;
|
|
166
137
|
}, {});
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
start
|
|
172
|
-
transform
|
|
173
|
-
|
|
174
|
-
return __generator(this, function (_a) {
|
|
175
|
-
controller.enqueue(textEncoder.encode(String(chunk)));
|
|
176
|
-
return [2];
|
|
177
|
-
});
|
|
178
|
-
});
|
|
138
|
+
}
|
|
139
|
+
initializeTransformStream() {
|
|
140
|
+
const textEncoder = new TextEncoder();
|
|
141
|
+
const stream = new TransformStream({
|
|
142
|
+
start() { },
|
|
143
|
+
async transform(chunk, controller) {
|
|
144
|
+
controller.enqueue(textEncoder.encode(String(chunk)));
|
|
179
145
|
},
|
|
180
|
-
flush
|
|
146
|
+
flush() { },
|
|
181
147
|
});
|
|
182
|
-
|
|
148
|
+
const writer = stream.writable.getWriter();
|
|
183
149
|
return {
|
|
184
|
-
stream
|
|
185
|
-
writer
|
|
150
|
+
stream,
|
|
151
|
+
writer,
|
|
186
152
|
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
export { XhrHttpHandler };
|
|
192
|
-
var isForbiddenRequestHeader = function (header) {
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
XhrHttpHandler.EVENTS = EVENTS;
|
|
156
|
+
const isForbiddenRequestHeader = (header) => {
|
|
193
157
|
header = header.toLowerCase();
|
|
194
158
|
if (header.startsWith("proxy-")) {
|
|
195
159
|
return true;
|
|
@@ -199,7 +163,7 @@ var isForbiddenRequestHeader = function (header) {
|
|
|
199
163
|
}
|
|
200
164
|
return forbiddenHeaders.includes(header);
|
|
201
165
|
};
|
|
202
|
-
|
|
166
|
+
const forbiddenHeaders = [
|
|
203
167
|
"Accept-Charset",
|
|
204
168
|
"Accept-Encoding",
|
|
205
169
|
"Access-Control-Request-Headers",
|
|
@@ -220,4 +184,4 @@ var forbiddenHeaders = [
|
|
|
220
184
|
"Transfer-Encoding",
|
|
221
185
|
"Upgrade",
|
|
222
186
|
"Via",
|
|
223
|
-
].map(
|
|
187
|
+
].map((_) => _.toLowerCase());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws-sdk/xhr-http-handler",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.183.0",
|
|
4
4
|
"description": "Provides a way to make requests using XMLHttpRequest",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types'",
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
"module": "./dist-es/index.js",
|
|
19
19
|
"types": "./dist-types/index.d.ts",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@aws-sdk/protocol-http": "3.
|
|
22
|
-
"@aws-sdk/querystring-builder": "3.
|
|
23
|
-
"@aws-sdk/types": "3.
|
|
24
|
-
"@aws-sdk/util-base64-browser": "3.
|
|
21
|
+
"@aws-sdk/protocol-http": "3.183.0",
|
|
22
|
+
"@aws-sdk/querystring-builder": "3.183.0",
|
|
23
|
+
"@aws-sdk/types": "3.183.0",
|
|
24
|
+
"@aws-sdk/util-base64-browser": "3.183.0",
|
|
25
25
|
"events": "3.3.0",
|
|
26
26
|
"tslib": "^2.3.1"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@aws-sdk/abort-controller": "3.
|
|
29
|
+
"@aws-sdk/abort-controller": "3.183.0",
|
|
30
30
|
"@tsconfig/recommended": "1.0.1",
|
|
31
31
|
"concurrently": "7.0.0",
|
|
32
32
|
"downlevel-dts": "0.10.1",
|