From 9120d17306e0536fb5332d53be2f35a5495e1431 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Thu, 16 Feb 2017 12:02:09 -0600 Subject: [PATCH] [plugin cli] Fix file:/// paths on Windows (#10083) * [plugin cli] Fix file:/// paths on Windows * [plugin cli] Stricter path checking, keeps support for file:// * [plugin cli] Add deprecation warning for file:// --- src/cli_plugin/install/__tests__/download.js | 33 +++++++++++++++++++- src/cli_plugin/install/download.js | 24 +++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/cli_plugin/install/__tests__/download.js b/src/cli_plugin/install/__tests__/download.js index d38728fe25578..656287c6bf1c2 100644 --- a/src/cli_plugin/install/__tests__/download.js +++ b/src/cli_plugin/install/__tests__/download.js @@ -6,7 +6,7 @@ import rimraf from 'rimraf'; import mkdirp from 'mkdirp'; import Logger from '../../lib/logger'; import { UnsupportedProtocolError } from '../../lib/errors'; -import { download, _downloadSingle } from '../download'; +import { download, _downloadSingle, _getFilePath, _checkFilePathDeprecation } from '../download'; import { join } from 'path'; describe('kibana cli', function () { @@ -133,6 +133,37 @@ describe('kibana cli', function () { }); + describe('_getFilePath', function () { + it('should decode paths', function () { + expect(_getFilePath('Test%20folder/file.zip')).to.equal('Test folder/file.zip'); + }); + + it('should remove the leading slash from windows paths', function () { + const platform = Object.getOwnPropertyDescriptor(process, 'platform'); + Object.defineProperty(process, 'platform', { value: 'win32' }); + + expect(_getFilePath('/C:/foo/bar')).to.equal('C:/foo/bar'); + + Object.defineProperty(process, 'platform', platform); + }); + + }); + + describe('Windows file:// deprecation', function () { + it('should log a warning if a file:// path is used', function () { + const platform = Object.getOwnPropertyDescriptor(process, 'platform'); + Object.defineProperty(process, 'platform', { value: 'win32' }); + const logger = { + log: sinon.spy() + }; + _checkFilePathDeprecation('file://foo/bar', logger); + _checkFilePathDeprecation('file:///foo/bar', logger); + expect(logger.log.callCount).to.be(1); + expect(logger.log.calledWith('Install paths with file:// are deprecated, use file:/// instead')).to.be(true); + Object.defineProperty(process, 'platform', platform); + }); + }); + describe('download', function () { it('should loop through bad urls until it finds a good one.', function () { const filePath = join(__dirname, 'replies/test_plugin.zip'); diff --git a/src/cli_plugin/install/download.js b/src/cli_plugin/install/download.js index 9083d38a338ea..f4018e29aa225 100644 --- a/src/cli_plugin/install/download.js +++ b/src/cli_plugin/install/download.js @@ -3,12 +3,34 @@ import downloadLocalFile from './downloaders/file'; import { UnsupportedProtocolError } from '../lib/errors'; import { parse } from 'url'; +function _isWindows() { + return /^win/.test(process.platform); +} + +export function _getFilePath(filePath, sourceUrl) { + const decodedPath = decodeURI(filePath); + const prefixedDrive = /^\/[a-zA-Z]:/.test(decodedPath); + if (_isWindows() && prefixedDrive) { + return decodedPath.slice(1); + } + + return decodedPath; +} + +export function _checkFilePathDeprecation(sourceUrl, logger) { + const twoSlashes = /^file:\/\/(?!\/)/.test(sourceUrl); + if (_isWindows() && twoSlashes) { + logger.log('Install paths with file:// are deprecated, use file:/// instead'); + } +} + export function _downloadSingle(settings, logger, sourceUrl) { const urlInfo = parse(sourceUrl); let downloadPromise; if (/^file/.test(urlInfo.protocol)) { - downloadPromise = downloadLocalFile(logger, decodeURI(urlInfo.path), settings.tempArchiveFile); + _checkFilePathDeprecation(sourceUrl, logger); + downloadPromise = downloadLocalFile(logger, _getFilePath(urlInfo.path, sourceUrl), settings.tempArchiveFile); } else if (/^https?/.test(urlInfo.protocol)) { downloadPromise = downloadHttpFile(logger, sourceUrl, settings.tempArchiveFile, settings.timeout); } else {