Skip to content

[BUG] File-upload proxy breaks sending files from WebDAV to server #24775

@Jonher937

Description

@Jonher937

Description:

The logic in app/file-upload/server/lib/proxy.js breaks uploading files from WebDAV to the RocketChat server.
Tested storage backends:

  • S3
  • Filesystem
  • GridFS

Steps to reproduce:

  1. Go to a room
  2. Add a WebDAV server down in the right corner, reload the page after doing so or RocketChat will throw you an error.
  3. Go down to the right corner again and try to send a file from WebDAV -> Room
  4. Watch the file get stuck on 0% and your browser XHR calls show ufsCreate: OK, then the POST returns 404 at which point the ufsDelete is called.

File upload from Disk -> Room still works fine.
File from WebDAV -> Room does not work.

Expected behavior:

File upload to be successfull.

Actual behavior:

File-upload server proxy gets involved and calls ufsCreate that returns the id and token, browser then send a POST to that and gets HTTP 404 back.

Server Setup Information:

  • Version of Rocket.Chat Server: develop 4.6.0 / 4.5.0 but occurs on previous version as well
  • Operating System: Linux
  • Deployment Method: Docker
  • Number of Running Instances: 1
  • DB Replicaset Oplog: N/A
  • NodeJS Version: 14.18.3
  • MongoDB Version: 4.4.4

Client Setup Information

  • Desktop App or Browser Version: Browser
  • Operating System: Linux

Additional context

Deployed a workaround in my test instance that simply does not import the proxy lib, then the upload works both via WebDAV and local disk.
https://github.com/Jonher937/Rocket.Chat/blob/8a1b901daa1efb258b9619b63d6f09e6b21a2eb7/app/file-upload/server/index.js#L3-L4
In my logs you can see that I seem to be hitting this:

// Proxy to other instance
const instance = InstanceStatus.getCollection().findOne({ _id: file.instanceId });
if (instance == null) {
res.writeHead(404);
res.end();
return;
}

Relevant logs:

I added some logging to reach the conclusion above.

Browser log

rocket

Diff

diff --git a/app/file-upload/server/lib/proxy.js b/app/file-upload/server/lib/proxy.js
index 53be1e285a..e77362400f 100644
--- a/app/file-upload/server/lib/proxy.js
+++ b/app/file-upload/server/lib/proxy.js
@@ -15,6 +15,7 @@ WebApp.connectHandlers.stack.unshift({
        route: '',
        handle: Meteor.bindEnvironment(function (req, res, next) {
                // Quick check to see if request should be catch
+               console.log({ "url": req.url, "storesPath": UploadFS.config.storesPath })
                if (!req.url.includes(`/${UploadFS.config.storesPath}/`)) {
                        return next();
                }
@@ -33,6 +34,9 @@ WebApp.connectHandlers.stack.unshift({
                const regExp = new RegExp('^/([^/?]+)/([^/?]+)$');
                const match = regExp.exec(path);
 
+               console.log("-- PATH  --")
+               console.log(match)
+               console.log("-----")
                // Request is not valid
                if (match === null) {
                        res.writeHead(400);
@@ -42,6 +46,9 @@ WebApp.connectHandlers.stack.unshift({
 
                // Get store
                const store = UploadFS.getStore(match[1]);
+               console.log("-- STORE  --")
+               console.log(store)
+               console.log("-----")
                if (!store) {
                        res.writeHead(404);
                        res.end();
@@ -51,6 +58,16 @@ WebApp.connectHandlers.stack.unshift({
                // Get file
                const fileId = match[2];
                const file = store.getCollection().findOne({ _id: fileId });
+
+               console.log("-- FILE  --")
+               console.log(file)
+               console.log(fileId)
+               console.log(InstanceStatus.id())
+               if (file.instanceId == InstanceStatus.id()) {
+                       console.log("Ids match")
+               }
+               console.log("-----")
+
                if (file === undefined) {
                        res.writeHead(404);
                        res.end();
@@ -65,6 +82,10 @@ WebApp.connectHandlers.stack.unshift({
                // Proxy to other instance
                const instance = InstanceStatus.getCollection().findOne({ _id: file.instanceId });
 
+               console.log("-- INSTANCE  --")
+               console.log(instance)
+               console.log("-----")
+
                if (instance == null) {
                        res.writeHead(404);
                        res.end();

Log

I20220309-10:03:20.767(0)? { url: '/api/v1/method.call/getWebdavFileList', storesPath: 'ufs' }
I20220309-10:03:21.039(0)? { url: '/api/v1/method.call/getWebdavFilePreview', storesPath: 'ufs' }
I20220309-10:03:21.041(0)? { url: '/api/v1/method.call/getWebdavFilePreview', storesPath: 'ufs' }
I20220309-10:03:22.172(0)? { url: '/api/v1/method.call/getFileFromWebdav', storesPath: 'ufs' }
I20220309-10:03:23.097(0)? { url: '/api/v1/method.call/ufsCreate', storesPath: 'ufs' }
I20220309-10:03:23.139(0)? {
I20220309-10:03:23.139(0)?   url: '/ufs/FileSystem:Uploads/38xZwsWKr3NwNcgtJ?token=d86b5aDbda&progress=1',
I20220309-10:03:23.140(0)?   storesPath: 'ufs'
I20220309-10:03:23.140(0)? }
I20220309-10:03:23.140(0)? -- PATH  --
I20220309-10:03:23.141(0)? [
I20220309-10:03:23.142(0)?   '/FileSystem:Uploads/38xZwsWKr3NwNcgtJ',
I20220309-10:03:23.142(0)?   'FileSystem:Uploads',
I20220309-10:03:23.142(0)?   '38xZwsWKr3NwNcgtJ',
I20220309-10:03:23.143(0)?   index: 0,
I20220309-10:03:23.143(0)?   input: '/FileSystem:Uploads/38xZwsWKr3NwNcgtJ',
I20220309-10:03:23.143(0)?   groups: undefined
I20220309-10:03:23.143(0)? ]
I20220309-10:03:23.144(0)? -----
I20220309-10:03:23.144(0)? -- STORE  --
I20220309-10:03:23.144(0)? LocalStore {
I20220309-10:03:23.145(0)?   options: {
I20220309-10:03:23.145(0)?     collection: Collection {
...
I20220309-10:03:23.149(0)?     },
I20220309-10:03:23.150(0)?     filter: Filter {
I20220309-10:03:23.150(0)?       options: [Object],
I20220309-10:03:23.150(0)?       onCheck: [Function: validateFileUpload]
I20220309-10:03:23.150(0)?     },
I20220309-10:03:23.151(0)?     name: 'FileSystem:Uploads',
...
I20220309-10:03:23.152(0)?     permissions: null,
I20220309-10:03:23.152(0)?     transformRead: null,
I20220309-10:03:23.153(0)?     transformWrite: null,
I20220309-10:03:23.153(0)?     mode: '0744',
I20220309-10:03:23.153(0)?     path: '/tmp/uploads',
I20220309-10:03:23.153(0)?     writeMode: '0744',
I20220309-10:03:23.154(0)?     getPath: [Function: getPath]
I20220309-10:03:23.154(0)?   },
I20220309-10:03:23.154(0)?   permissions: StorePermissions {
I20220309-10:03:23.154(0)?     actions: {
I20220309-10:03:23.154(0)?       insert: [Function: insert],
I20220309-10:03:23.155(0)?       remove: [Function: remove],
I20220309-10:03:23.155(0)?       update: [Function: update]
I20220309-10:03:23.155(0)?     }
I20220309-10:03:23.155(0)?   },
...
I20220309-10:03:23.159(0)? }
I20220309-10:03:23.159(0)? -----
I20220309-10:03:23.160(0)? -- FILE  --
I20220309-10:03:23.160(0)? {
I20220309-10:03:23.161(0)?   _id: '38xZwsWKr3NwNcgtJ',
I20220309-10:03:23.161(0)?   name: 'test.txt',
I20220309-10:03:23.162(0)?   size: 3,
I20220309-10:03:23.162(0)?   type: 'text/plain',
I20220309-10:03:23.162(0)?   rid: 'GENERAL',
I20220309-10:03:23.162(0)?   description: '',
I20220309-10:03:23.163(0)?   store: 'FileSystem:Uploads',
I20220309-10:03:23.163(0)?   complete: false,
I20220309-10:03:23.163(0)?   uploading: false,
I20220309-10:03:23.163(0)?   extension: 'txt',
I20220309-10:03:23.163(0)?   progress: 0,
I20220309-10:03:23.164(0)?   userId: 'Ph7hRjZJNa52aq8Sc'
I20220309-10:03:23.164(0)? }
I20220309-10:03:23.164(0)? 38xZwsWKr3NwNcgtJ
I20220309-10:03:23.164(0)? ywFfojfTnmANhsYpv
I20220309-10:03:23.164(0)? -----
I20220309-10:03:23.165(0)? -- INSTANCE  --
I20220309-10:03:23.165(0)? undefined
I20220309-10:03:23.165(0)? -----
I20220309-10:03:23.258(0)? { url: '/api/v1/method.call/ufsDelete', storesPath: 'ufs' }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions