support uploading blobs in hs api

This commit is contained in:
Bruno Windels 2020-11-11 10:45:23 +01:00
parent c278b0f4a3
commit 9f2c7c1e32
3 changed files with 35 additions and 5 deletions

View File

@ -55,6 +55,26 @@ class RequestWrapper {
} }
} }
function encodeBody(body) {
if (body.nativeBlob && body.mimeType) {
const blob = body;
return {
mimeType: blob.mimeType,
body: blob, // will be unwrapped in request fn
length: blob.size
};
} else if (typeof body === "object") {
const json = JSON.stringify(body);
return {
mimeType: "application/json",
body: json,
length: body.length
};
} else {
throw new Error("Unknown body type: " + body);
}
}
export class HomeServerApi { export class HomeServerApi {
constructor({homeServer, accessToken, request, createTimeout, reconnector}) { constructor({homeServer, accessToken, request, createTimeout, reconnector}) {
// store these both in a closure somehow so it's harder to get at in case of XSS? // store these both in a closure somehow so it's harder to get at in case of XSS?
@ -73,22 +93,24 @@ export class HomeServerApi {
_baseRequest(method, url, queryParams, body, options, accessToken) { _baseRequest(method, url, queryParams, body, options, accessToken) {
const queryString = encodeQueryParams(queryParams); const queryString = encodeQueryParams(queryParams);
url = `${url}?${queryString}`; url = `${url}?${queryString}`;
let bodyString; let encodedBody;
const headers = new Map(); const headers = new Map();
if (accessToken) { if (accessToken) {
headers.set("Authorization", `Bearer ${accessToken}`); headers.set("Authorization", `Bearer ${accessToken}`);
} }
headers.set("Accept", "application/json"); headers.set("Accept", "application/json");
if (body) { if (body) {
headers.set("Content-Type", "application/json"); const encoded = encodeBody(body);
bodyString = JSON.stringify(body); headers.set("Content-Type", encoded.mimeType);
headers.set("Content-Length", encoded.length);
encodedBody = encoded.body;
} }
const requestResult = this._requestFn(url, { const requestResult = this._requestFn(url, {
method, method,
headers, headers,
body: bodyString, body: encodedBody,
timeout: options?.timeout, timeout: options?.timeout,
format: "json" format: "json" // response format
}); });
const wrapper = new RequestWrapper(method, url, requestResult); const wrapper = new RequestWrapper(method, url, requestResult);

View File

@ -53,6 +53,10 @@ class RequestResult {
export function createFetchRequest(createTimeout) { export function createFetchRequest(createTimeout) {
return function fetchRequest(url, {method, headers, body, timeout, format, cache = false}) { return function fetchRequest(url, {method, headers, body, timeout, format, cache = false}) {
const controller = typeof AbortController === "function" ? new AbortController() : null; const controller = typeof AbortController === "function" ? new AbortController() : null;
// if a BlobHandle, take native blob
if (body?.nativeBlob) {
body = body.nativeBlob;
}
let options = {method, body}; let options = {method, body};
if (controller) { if (controller) {
options = Object.assign(options, { options = Object.assign(options, {

View File

@ -52,6 +52,10 @@ function send(url, {method, headers, timeout, body, format}) {
xhr.timeout = timeout; xhr.timeout = timeout;
} }
// if a BlobHandle, take native blob
if (body?.nativeBlob) {
body = body.nativeBlob;
}
xhr.send(body || null); xhr.send(body || null);
return xhr; return xhr;