浏览代码

[frontend] fix to upload files to folders with non ascii names for s3 and abfs (#2907)

Co-authored-by: Björn Alm <balm@cloudera.com>
Bjorn Alm 3 年之前
父节点
当前提交
f5407f95a3
共有 1 个文件被更改,包括 30 次插入3 次删除
  1. 30 3
      desktop/core/src/desktop/js/ext/fileuploader.custom.js

+ 30 - 3
desktop/core/src/desktop/js/ext/fileuploader.custom.js

@@ -29,6 +29,35 @@ import $ from 'jquery';
 // Helper functions
 //
 
+const splitProtocolAndPathName = (fullUrl) => {
+    // The path name can contain one or more questionmarks (?) that are NOT specifying 
+    // the search/query start for these urls so we use a custom regex instead of URL() to parse.
+    const splitRegex = /^(\w*:)?(.*)$/i;
+    const [match, protocol, pathName] = splitRegex.exec(fullUrl);
+    return [protocol ?? '', pathName ]
+}
+
+const isUnicodeAlphaNumeric = /^[\p{L}\p{N}]*$/u;
+const encodeUploadPath = (char) => {            
+    const needsEncoding = !isUnicodeAlphaNumeric.test(char) && char !== '/' && char !== '?';
+    return needsEncoding ? encodeURIComponent(char) : char;
+}
+
+/**
+ * Fixes encoding issues with the destination folder url.
+ * Some special non-alphanumeric characters like plus (+) and ampersand (&) needs encoding
+ * while the slash (/) which represents a directory and question mark (?) should not be encoded. 
+ * Alphanumeric characters that are non ASCII (e.g. åäö) should not be encoded since that
+ * will fail if the target is s3 or abfs.     
+ * @param {string} destination The "destination url" used for the filesystem. Might not be a valid url.
+ */
+const fixUploadDestination = (destination) => {
+    const decodedDestination = decodeURIComponent(destination);
+    const [protocol, path] = splitProtocolAndPathName(decodedDestination);
+    const updatedPath = [...path].map(encodeUploadPath).join('');
+    return `${protocol}${updatedPath}`;        
+}
+
 
 let qq = {};
 
@@ -1260,9 +1289,7 @@ qq.extend(qq.UploadHandlerXhr.prototype, {
         formData.append(params.fileFieldLabel, file, file.name.normalize('NFC'));
         formData.append('dest', params.dest);
 
-        // Encoding is needed to support folder names with some special 
-        // non alfanumeric characters like plus (+) and ampersand (&)
-        var destination = encodeURIComponent(params.dest);
+        const destination = fixUploadDestination(params.dest);
         var action = this._options.action + "?dest=" + destination;
         xhr.open("POST", action, true);
         xhr.send(formData);