Merge branch '21128-toolbar-context-menu'
[arvados-workbench2.git] / src / common / webdav.ts
index 17032768fd00436ef92cb4b63d156d0456ddc442..1f3da0d6148f4bb45c2406c8e544f35f125aa990 100644 (file)
@@ -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': 'no-cache'
+        },
     };
 
     constructor(config?: Partial<WebDAVDefaults>, 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({
@@ -74,25 +94,37 @@ export class WebDAV {
             this.defaults.baseURL = this.defaults.baseURL.replace(/\/+$/, '');
             r.open(config.method,
                 `${this.defaults.baseURL
-                    ? this.defaults.baseURL+'/'
-                    : ''}${config.url}`);
+                    ? 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);
             });
@@ -124,4 +156,4 @@ interface RequestConfig {
     headers?: { [key: string]: string };
     data?: any;
     onUploadProgress?: (event: ProgressEvent) => void;
-}
\ No newline at end of file
+}