Skip to content

Commit

Permalink
Merge pull request #7304 from RocketChat/hotfix/rc-avatar-upload-proxy
Browse files Browse the repository at this point in the history
[FIX] Proxy upload to correct instance
  • Loading branch information
rodrigok committed Jun 27, 2017
2 parents f1e9f70 + f96832c commit b031171
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/rocketchat-file-upload/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Package.onUse(function(api) {
api.addFiles('client/lib/fileUploadHandler.js', 'client');

api.addFiles('server/lib/FileUpload.js', 'server');
api.addFiles('server/lib/proxy.js', 'server');
api.addFiles('server/lib/requests.js', 'server');

api.addFiles('server/config/_configUploadStorage.js', 'server');
Expand Down
91 changes: 91 additions & 0 deletions packages/rocketchat-file-upload/server/lib/proxy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* globals UploadFS, InstanceStatus */

import http from 'http';
import URL from 'url';

const logger = new Logger('UploadProxy');

WebApp.connectHandlers.stack.unshift({
route: '',
handle: Meteor.bindEnvironment(function(req, res, next) {
// Quick check to see if request should be catch
if (req.url.indexOf(UploadFS.config.storesPath) === -1) {
return next();
}

logger.debug('Upload URL:', req.url);

if (req.method !== 'POST') {
return next();
}

// Remove store path
const parsedUrl = URL.parse(req.url);
const path = parsedUrl.pathname.substr(UploadFS.config.storesPath.length + 1);

// Get store
const regExp = new RegExp('^\/([^\/\?]+)\/([^\/\?]+)$');
const match = regExp.exec(path);

// Request is not valid
if (match === null) {
res.writeHead(400);
res.end();
return;
}

// Get store
const store = UploadFS.getStore(match[1]);
if (!store) {
res.writeHead(404);
res.end();
return;
}

// Get file
const fileId = match[2];
const file = store.getCollection().findOne({_id: fileId});
if (file === undefined) {
res.writeHead(404);
res.end();
return;
}

if (file.instanceId === InstanceStatus.id()) {
logger.debug('Correct instance');
return next();
}

// Proxy to other instance
const instance = InstanceStatus.getCollection().findOne({_id: file.instanceId});

if (instance == null) {
res.writeHead(404);
res.end();
return;
}

if (instance.extraInformation.host === process.env.INSTANCE_IP && RocketChat.isDocker() === false) {
instance.extraInformation.host = 'localhost';
}

logger.debug('Wrong instance, proxing to:', `${ instance.extraInformation.host }:${ instance.extraInformation.port }`);

const options = {
hostname: instance.extraInformation.host,
port: instance.extraInformation.port,
path: req.url,
method: 'POST'
};

const proxy = http.request(options, function(proxy_res) {
proxy_res.pipe(res, {
end: true
});
});

req.pipe(proxy, {
end: true
});
})
});
6 changes: 6 additions & 0 deletions packages/rocketchat-lib/server/models/Avatars.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
/* globals InstanceStatus */

RocketChat.models.Avatars = new class extends RocketChat.models._Base {
constructor() {
super('avatars');

this.model.before.insert((userId, doc) => {
doc.instanceId = InstanceStatus.id();
});

this.tryEnsureIndex({ name: 1 });
}

Expand Down
6 changes: 6 additions & 0 deletions packages/rocketchat-lib/server/models/Uploads.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
/* globals InstanceStatus */

RocketChat.models.Uploads = new class extends RocketChat.models._Base {
constructor() {
super('uploads');

this.model.before.insert((userId, doc) => {
doc.instanceId = InstanceStatus.id();
});

this.tryEnsureIndex({ 'rid': 1 });
this.tryEnsureIndex({ 'uploadedAt': 1 });
}
Expand Down
1 change: 1 addition & 0 deletions server/startup/avatar.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* globals FileUpload */

Meteor.startup(function() {
WebApp.connectHandlers.use('/avatar/', Meteor.bindEnvironment(function(req, res/*, next*/) {
const params = {
Expand Down

0 comments on commit b031171

Please sign in to comment.