import http from 'http'; import URL from 'url'; import { Meteor } from 'meteor/meteor'; import { WebApp } from 'meteor/webapp'; import { UploadFS } from 'meteor/jalik:ufs'; import { InstanceStatus } from 'meteor/konecty:multiple-instances-status'; import { Logger } from '../../../logger'; import { isDocker } from '../../../utils'; 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.includes(`/${UploadFS.config.storesPath}/`)) { return next(); } logger.debug({ msg: 'Upload URL:', 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 && 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.originalUrl, method: 'POST', }; logger.warn( 'UFS proxy middleware is deprecated as this upload method is not being used by Web/Mobile Clients. See this: https://docs.rocket.chat/api/rest-api/methods/rooms/upload', ); const proxy = http.request(options, function (proxy_res) { proxy_res.pipe(res, { end: true, }); }); req.pipe(proxy, { end: true, }); }), });