diff --git a/spec/batch.spec.js b/spec/batch.spec.js new file mode 100644 index 00000000..c4ae81f0 --- /dev/null +++ b/spec/batch.spec.js @@ -0,0 +1,44 @@ +var batch = require('../src/batch'); + +const originalURL = '/parse/batch'; +const serverURL = 'http://localhost:1234/parse'; +const serverURL1 = 'http://localhost:1234/1'; +const serverURLNaked = 'http://localhost:1234/'; +const publicServerURL = 'http://domain.com/parse'; +const publicServerURLNaked = 'http://domain.com/'; + +describe('batch', () => { + it('should return the proper url', () => { + let internalURL = batch.makeBatchRoutingPathFunction(originalURL)('/parse/classes/Object'); + + expect(internalURL).toEqual('/classes/Object'); + }); + + it('should return the proper url same public/local endpoint', () => { + let originalURL = '/parse/batch'; + let internalURL = batch.makeBatchRoutingPathFunction(originalURL, serverURL, publicServerURL)('/parse/classes/Object'); + + expect(internalURL).toEqual('/classes/Object'); + }); + + it('should return the proper url with different public/local mount', () => { + let originalURL = '/parse/batch'; + let internalURL = batch.makeBatchRoutingPathFunction(originalURL, serverURL1, publicServerURL)('/parse/classes/Object'); + + expect(internalURL).toEqual('/classes/Object'); + }); + + it('should return the proper url with naked public', () => { + let originalURL = '/batch'; + let internalURL = batch.makeBatchRoutingPathFunction(originalURL, serverURL, publicServerURLNaked)('/classes/Object'); + + expect(internalURL).toEqual('/classes/Object'); + }); + + it('should return the proper url with naked local', () => { + let originalURL = '/parse/batch'; + let internalURL = batch.makeBatchRoutingPathFunction(originalURL, serverURLNaked, publicServerURL)('/parse/classes/Object'); + + expect(internalURL).toEqual('/classes/Object'); + }); +}); diff --git a/src/batch.js b/src/batch.js index 72418a6e..54cd7528 100644 --- a/src/batch.js +++ b/src/batch.js @@ -1,7 +1,8 @@ -var Parse = require('parse/node').Parse; - +const Parse = require('parse/node').Parse; +const url = require('url'); +const path = require('path'); // These methods handle batch requests. -var batchPath = '/batch'; +const batchPath = '/batch'; // Mounts a batch-handler onto a PromiseRouter. function mountOnto(router) { @@ -10,6 +11,48 @@ function mountOnto(router) { }); } +function parseURL(URL) { + if (typeof URL === 'string') { + return url.parse(URL) + } + return undefined; +} + +function makeBatchRoutingPathFunction(originalUrl, serverURL, publicServerURL) { + serverURL = serverURL ? parseURL(serverURL) : undefined; + publicServerURL = publicServerURL ? parseURL(publicServerURL): undefined; + + let apiPrefixLength = originalUrl.length - batchPath.length; + let apiPrefix = originalUrl.slice(0, apiPrefixLength); + + let makeRoutablePath = function(requestPath) { + // The routablePath is the path minus the api prefix + if (requestPath.slice(0, apiPrefix.length) != apiPrefix) { + throw new Parse.Error( + Parse.Error.INVALID_JSON, + 'cannot route batch path ' + requestPath); + } + return path.join('/', requestPath.slice(apiPrefix.length)); + } + + if (serverURL && publicServerURL + && (serverURL.path != publicServerURL.path)) { + let localPath = serverURL.path; + let publicPath = publicServerURL.path; + // Override the api prefix + apiPrefix = localPath; + return function(requestPath) { + // Build the new path by removing the public path + // and joining with the local path + let newPath = path.join('/', localPath, '/' , requestPath.slice(publicPath.length)); + // Use the method for local routing + return makeRoutablePath(newPath); + } + } + + return makeRoutablePath; +} + // Returns a promise for a {response} object. // TODO: pass along auth correctly function handleBatch(router, req) { @@ -26,19 +69,13 @@ function handleBatch(router, req) { if (!req.originalUrl.endsWith(batchPath)) { throw 'internal routing problem - expected url to end with batch'; } - var apiPrefixLength = req.originalUrl.length - batchPath.length; - var apiPrefix = req.originalUrl.slice(0, apiPrefixLength); + + const makeRoutablePath = makeBatchRoutingPathFunction(req.originalUrl, req.config.serverURL, req.config.publicServerURL); const promises = req.body.requests.map((restRequest) => { - // The routablePath is the path minus the api prefix - if (restRequest.path.slice(0, apiPrefixLength) != apiPrefix) { - throw new Parse.Error( - Parse.Error.INVALID_JSON, - 'cannot route batch path ' + restRequest.path); - } - var routablePath = restRequest.path.slice(apiPrefixLength); + const routablePath = makeRoutablePath(restRequest.path); // Construct a request that we can send to a handler - var request = { + const request = { body: restRequest.body, config: req.config, auth: req.auth, @@ -58,5 +95,6 @@ function handleBatch(router, req) { } module.exports = { - mountOnto: mountOnto + mountOnto, + makeBatchRoutingPathFunction };