From 0376fbe109978bacdcbc4c81f5deed162de24f42 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 2 Sep 2015 09:33:20 -0600 Subject: [PATCH] Resolve URLs relative to location if defined --- api/request.js | 13 ++++++++++- test/api/request.test.js | 50 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/api/request.js b/api/request.js index a55caa6..e7a64a6 100644 --- a/api/request.js +++ b/api/request.js @@ -29,7 +29,18 @@ var defaultHeaders = { * @private */ function parseConfig(config) { - var base = config.url ? url.parse(config.url, true) : {query: {}}; + var base; + if (config.url) { + var resolved; + if (typeof location !== 'undefined') { + resolved = url.resolve(location.href, config.url); + } else { + resolved = config.url; + } + base = url.parse(resolved, true); + } else { + base = {query: {}}; + } if (config.query) { config.path = url.format({ pathname: base.pathname || config.pathname || '/', diff --git a/test/api/request.test.js b/test/api/request.test.js index 0a61f53..fe4a129 100644 --- a/test/api/request.test.js +++ b/test/api/request.test.js @@ -449,6 +449,14 @@ describe('api/request', function() { var parseConfig = req.parseConfig; var defaultHeaders = {accept: 'application/json'}; + var existingLocation; + beforeEach(function() { + existingLocation = global.location; + }); + afterEach(function() { + global.location = existingLocation; + }); + it('generates request options from a URL', function() { var config = { url: 'http://example.com' @@ -465,6 +473,48 @@ describe('api/request', function() { assert.deepEqual(parseConfig(config), options); }); + it('resolves a relative URL if location is defined', function() { + global.location = { + href: 'http://example.com/foo/bar.html' + }; + + var config = { + url: './relative/path/to/data.json' + }; + + var options = { + protocol: 'http:', + hostname: 'example.com', + port: '80', + method: 'GET', + path: '/foo/relative/path/to/data.json', + headers: defaultHeaders + }; + + assert.deepEqual(parseConfig(config), options); + }); + + it('works for root relative URLs', function() { + global.location = { + href: 'http://example.com/foo/bar.html' + }; + + var config = { + url: '/root/path/to/data.json' + }; + + var options = { + protocol: 'http:', + hostname: 'example.com', + port: '80', + method: 'GET', + path: '/root/path/to/data.json', + headers: defaultHeaders + }; + + assert.deepEqual(parseConfig(config), options); + }); + it('adds user provided headers', function() { var config = { url: 'http://example.com',