2020-08-05 22:29:16 +05:30
|
|
|
/*
|
|
|
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2020-08-05 21:07:37 +05:30
|
|
|
import {
|
|
|
|
AbortError,
|
|
|
|
ConnectionError
|
|
|
|
} from "../../error.js";
|
2020-10-02 17:32:59 +05:30
|
|
|
import {addCacheBuster} from "../common.js";
|
2020-08-05 21:07:37 +05:30
|
|
|
|
|
|
|
class RequestResult {
|
|
|
|
constructor(promise, xhr) {
|
|
|
|
this._promise = promise;
|
|
|
|
this._xhr = xhr;
|
|
|
|
}
|
|
|
|
|
|
|
|
abort() {
|
|
|
|
this._xhr.abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
response() {
|
|
|
|
return this._promise;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function send(url, options) {
|
|
|
|
const xhr = new XMLHttpRequest();
|
|
|
|
xhr.open(options.method, url);
|
|
|
|
if (options.headers) {
|
|
|
|
for(const [name, value] of options.headers.entries()) {
|
|
|
|
xhr.setRequestHeader(name, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (options.timeout) {
|
|
|
|
xhr.timeout = options.timeout;
|
|
|
|
}
|
|
|
|
|
|
|
|
xhr.send(options.body || null);
|
|
|
|
|
|
|
|
return xhr;
|
|
|
|
}
|
|
|
|
|
|
|
|
function xhrAsPromise(xhr, method, url) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
xhr.addEventListener("load", () => resolve(xhr));
|
|
|
|
xhr.addEventListener("abort", () => reject(new AbortError()));
|
|
|
|
xhr.addEventListener("error", () => reject(new ConnectionError(`Error ${method} ${url}`)));
|
|
|
|
xhr.addEventListener("timeout", () => reject(new ConnectionError(`Timeout ${method} ${url}`, true)));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export function xhrRequest(url, options) {
|
|
|
|
url = addCacheBuster(url);
|
|
|
|
const xhr = send(url, options);
|
|
|
|
const promise = xhrAsPromise(xhr, options.method, url).then(xhr => {
|
|
|
|
const {status} = xhr;
|
2020-10-05 20:48:05 +05:30
|
|
|
let body = null;
|
2020-08-05 21:07:37 +05:30
|
|
|
if (xhr.getResponseHeader("Content-Type") === "application/json") {
|
2020-10-06 16:32:18 +05:30
|
|
|
body = JSON.parse(xhr.responseText);
|
2020-08-05 21:07:37 +05:30
|
|
|
}
|
|
|
|
return {status, body};
|
|
|
|
});
|
|
|
|
return new RequestResult(promise, xhr);
|
|
|
|
}
|