From 195c8e5ff5af6506e5c3e9423cd3c6e839b9cc86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Gabriel=20Quaresma?= Date: Mon, 7 Mar 2022 14:53:57 -0300 Subject: [PATCH] Returned error treated when requesting uncommon URL (#3544) * Fixing error returned when requesting illegal URL * Adding unit tests http.js * Fixing error message axios invalid request from browser * Adding unit tests requests.spec.js * Adding at utils.js a new method: getProtocol Co-authored-by: Jay --- lib/adapters/http.js | 10 ++++- lib/adapters/xhr.js | 14 +++++++ lib/utils.js | 18 +++++++++ test/specs/requests.spec.js | 49 ++++++++++++++++++++++ test/unit/adapters/http.js | 81 ++++++++++++++++++++++++++++++++++++- 5 files changed, 170 insertions(+), 2 deletions(-) diff --git a/lib/adapters/http.js b/lib/adapters/http.js index a6d7cddc22..a6b2b2230d 100755 --- a/lib/adapters/http.js +++ b/lib/adapters/http.js @@ -122,7 +122,15 @@ module.exports = function httpAdapter(config) { // Parse url var fullPath = buildFullPath(config.baseURL, config.url); var parsed = url.parse(fullPath); - var protocol = parsed.protocol || 'http:'; + var protocol = utils.getProtocol(parsed.protocol); + + if (parsed.path === null) { + return reject(createError('Malformed URL ' + fullPath, config)); + } + + if (!utils.supportedProtocols.includes(protocol)) { + return reject(createError('Unsupported protocol ' + protocol, config)); + } if (!auth && parsed.auth) { var urlAuth = parsed.auth.split(':'); diff --git a/lib/adapters/xhr.js b/lib/adapters/xhr.js index e58625aaa0..8388c2aac5 100644 --- a/lib/adapters/xhr.js +++ b/lib/adapters/xhr.js @@ -8,6 +8,7 @@ var buildFullPath = require('../core/buildFullPath'); var parseHeaders = require('./../helpers/parseHeaders'); var isURLSameOrigin = require('./../helpers/isURLSameOrigin'); var createError = require('../core/createError'); +var url = require('url'); var transitionalDefaults = require('../defaults/transitional'); var Cancel = require('../cancel/Cancel'); @@ -41,6 +42,9 @@ module.exports = function xhrAdapter(config) { } var fullPath = buildFullPath(config.baseURL, config.url); + var parsed = url.parse(fullPath); + var protocol = utils.getProtocol(parsed.protocol); + request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true); // Set the request timeout in MS @@ -206,6 +210,16 @@ module.exports = function xhrAdapter(config) { requestData = null; } + if (parsed.path === null) { + reject(createError('Malformed URL ' + fullPath, config)); + return; + } + + if (!utils.supportedProtocols.includes(protocol)) { + reject(createError('Unsupported protocol ' + protocol, config)); + return; + } + // Send the request request.send(requestData); }); diff --git a/lib/utils.js b/lib/utils.js index f0f90432c5..00446c7d31 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -6,6 +6,22 @@ var bind = require('./helpers/bind'); var toString = Object.prototype.toString; +/** + * Array with axios supported protocols. + */ +var supportedProtocols = [ 'http:', 'https:', 'file:' ]; + +/** + * Returns URL protocol passed as param if is not undefined or null, + * otherwise just returns 'http:' + * + * @param {String} protocol The String value of URL protocol + * @returns {String} Protocol if the value is not undefined or null + */ +function getProtocol(protocol) { + return protocol || 'http:'; +} + /** * Determine if a value is an Array * @@ -324,6 +340,8 @@ function stripBOM(content) { } module.exports = { + supportedProtocols: supportedProtocols, + getProtocol: getProtocol, isArray: isArray, isArrayBuffer: isArrayBuffer, isBuffer: isBuffer, diff --git a/test/specs/requests.spec.js b/test/specs/requests.spec.js index a5aa81aab4..95674f3c2c 100644 --- a/test/specs/requests.spec.js +++ b/test/specs/requests.spec.js @@ -481,4 +481,53 @@ describe('requests', function () { done(); }); }); + + it('should support HTTP protocol', function (done) { + var response; + + axios.get('/foo') + .then(function (res) { + response = res + }) + + getAjaxRequest().then(function (request) { + expect(request.method).toBe('GET'); + request.respondWith({ + status: 200 + }); + done(); + }); + }); + + it('should support HTTPS protocol', function (done) { + var response; + axios.get('https://www.google.com') + .then(function (res) { + response = res + }) + + getAjaxRequest().then(function (request) { + expect(request.method).toBe('GET'); + request.respondWith({ + status: 200 + }); + done(); + }); + }); + + it('should return malformed url error message', function (done) { + axios.get('tel:484-695-3408') + .catch(function (error) { + expect(error.message).toEqual('Malformed URL tel:484-695-3408') + done(); + }) + }); + + it('should return unsupported protocol error message', function (done) { + axios.get('ftp:google.com') + .catch(function (error) { + expect(error.message).toEqual('Unsupported protocol ftp:') + done(); + }) + }); }); diff --git a/test/unit/adapters/http.js b/test/unit/adapters/http.js index b0cca236df..6976f8c2f8 100644 --- a/test/unit/adapters/http.js +++ b/test/unit/adapters/http.js @@ -1038,6 +1038,86 @@ describe('supports http with nodejs', function () { }); }); + it('should support HTTP protocol', function (done) { + server = http.createServer(function (req, res) { + setTimeout(function () { + res.end(); + }, 1000); + }).listen(4444, function () { + axios.get('http://localhost:4444') + .then(function (res) { + assert.equal(res.request.agent.protocol, 'http:'); + done(); + }) + }) + }); + + it('should support HTTPS protocol', function (done) { + server = http.createServer(function (req, res) { + setTimeout(function () { + res.end(); + }, 1000); + }).listen(4444, function () { + axios.get('https://www.google.com') + .then(function (res) { + assert.equal(res.request.agent.protocol, 'https:'); + done(); + }) + }) + }); + + it('should return malformed URL', function (done) { + var success = false, failure = false; + var error; + + server = http.createServer(function (req, res) { + setTimeout(function () { + res.end(); + }, 1000); + }).listen(4444, function () { + axios.get('tel:484-695-3408') + .then(function (res) { + success = true; + }).catch(function (err) { + error = err; + failure = true; + }) + + setTimeout(function () { + assert.equal(success, false, 'request should not succeed'); + assert.equal(failure, true, 'request should fail'); + assert.equal(error.message, 'Malformed URL tel:484-695-3408'); + done(); + }, 300); + }) + }); + + it('should return unsupported protocol', function (done) { + var success = false, failure = false; + var error; + + server = http.createServer(function (req, res) { + setTimeout(function () { + res.end(); + }, 1000); + }).listen(4444, function () { + axios.get('ftp:google.com') + .then(function (res) { + success = true; + }).catch(function (err) { + error = err; + failure = true; + }) + + setTimeout(function () { + assert.equal(success, false, 'request should not succeed'); + assert.equal(failure, true, 'request should fail'); + assert.equal(error.message, 'Unsupported protocol ftp:'); + done(); + }, 300); + }) + }); + it('should supply a user-agent if one is not specified', function (done) { server = http.createServer(function (req, res) { assert.equal(req.headers["user-agent"], 'axios/' + pkg.version); @@ -1097,6 +1177,5 @@ describe('supports http with nodejs', function () { }); }); }); - });