X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/4c6f753bed0deee685b469be0b399bd61d457de8..157416e6afb2c0e1a206de4707a3984796e08bbd:/src/common/webdav.ts diff --git a/src/common/webdav.ts b/src/common/webdav.ts index 3f55a841..bb8a68bd 100644 --- a/src/common/webdav.ts +++ b/src/common/webdav.ts @@ -2,19 +2,33 @@ // // SPDX-License-Identifier: AGPL-3.0 +import { customEncodeURI } from "./url"; + export class WebDAV { - defaults: WebDAVDefaults = { + private defaults: WebDAVDefaults = { baseURL: '', - headers: {}, + headers: { + 'Cache-Control': 'must-revalidate' + }, }; constructor(config?: Partial, private createRequest = () => new XMLHttpRequest()) { if (config) { - this.defaults = { ...this.defaults, ...config }; + this.defaults = { + ...this.defaults, + ...config, + headers: { + ...this.defaults.headers, + ...config.headers + }, + }; } } + getBaseUrl = (): string => this.defaults.baseURL; + setAuthorization = (token?) => this.defaults.headers.Authorization = token; + propfind = (url: string, config: WebDAVRequestConfig = {}) => this.request({ ...config, url, @@ -28,6 +42,12 @@ export class WebDAV { data }) + get = (url: string, config: WebDAVRequestConfig = {}) => + this.request({ + ...config, url, + method: 'GET' + }) + upload = (url: string, files: File[], config: WebDAVRequestConfig = {}) => { return Promise.all( files.map(file => this.request({ @@ -42,14 +62,24 @@ export class WebDAV { this.request({ ...config, url, method: 'COPY', - headers: { ...config.headers, Destination: this.defaults.baseURL + destination } + headers: { + ...config.headers, + Destination: this.defaults.baseURL + ? this.defaults.baseURL.replace(/\/+$/, '') + '/' + destination.replace(/^\/+/, '') + : destination + } }) move = (url: string, destination: string, config: WebDAVRequestConfig = {}) => this.request({ ...config, url, method: 'MOVE', - headers: { ...config.headers, Destination: this.defaults.baseURL + destination } + headers: { + ...config.headers, + Destination: this.defaults.baseURL + ? this.defaults.baseURL.replace(/\/+$/, '') + '/' + destination.replace(/^\/+/, '') + : destination + } }) delete = (url: string, config: WebDAVRequestConfig = {}) => @@ -61,24 +91,40 @@ export class WebDAV { private request = (config: RequestConfig) => { return new Promise((resolve, reject) => { const r = this.createRequest(); - r.open(config.method, `${this.defaults.baseURL}/${config.url}`); + this.defaults.baseURL = this.defaults.baseURL.replace(/\/+$/, ''); + r.open(config.method, + `${this.defaults.baseURL + ? this.defaults.baseURL+'/' + : ''}${customEncodeURI(config.url)}`); + const headers = { ...this.defaults.headers, ...config.headers }; Object .keys(headers) .forEach(key => r.setRequestHeader(key, headers[key])); + if (!(window as any).cancelTokens) { + Object.assign(window, { cancelTokens: {} }); + } + + (window as any).cancelTokens[config.url] = () => { + resolve(r); + r.abort(); + } + if (config.onUploadProgress) { r.upload.addEventListener('progress', config.onUploadProgress); } + // This event gets triggered on *any* server response r.addEventListener('load', () => { - if (r.status === 404) { + if (r.status >= 400) { return reject(r); } else { return resolve(r); } }); + // This event gets triggered on network errors r.addEventListener('error', () => { return reject(r); }); @@ -110,4 +156,4 @@ interface RequestConfig { headers?: { [key: string]: string }; data?: any; onUploadProgress?: (event: ProgressEvent) => void; -} \ No newline at end of file +}