diff --git a/src/dapi/http/NodeHttpImpl.js b/src/dapi/http/NodeHttpImpl.js index 495e2e1..541b332 100644 --- a/src/dapi/http/NodeHttpImpl.js +++ b/src/dapi/http/NodeHttpImpl.js @@ -45,6 +45,12 @@ module.exports = Class( 'NodeHttpImpl' ) */ 'private _urlParser': '', + /** + * Request origin + * @type {string} + */ + 'private _origin': '', + /** * Initialize with protocol handlers and URL parser @@ -53,13 +59,17 @@ module.exports = Class( 'NodeHttpImpl' ) * to a handler object conforming to Node's http(s) APIs---that is, it * should provide a `#request` method. * + * `origin` is prepended to all request URLs. + * * @param {Object} proto_handlers protocol handler key-value map * @param {Object} url_parser URL parser + * @param {string} origin request origin */ - constructor( proto_handlers, url_parser ) + constructor( proto_handlers, url_parser, origin ) { this._protoHandlers = proto_handlers; this._urlParser = url_parser; + this._origin = ( origin !== undefined ) ? ''+origin : ''; }, @@ -79,7 +89,7 @@ module.exports = Class( 'NodeHttpImpl' ) */ 'public requestData'( url, method, data, callback ) { - const options = this._urlParser.parse( url ); + const options = this._parseUrl( url ); const protocol = options.protocol.replace( /:$/, '' ); const handler = this._protoHandlers[ protocol ]; @@ -120,6 +130,25 @@ module.exports = Class( 'NodeHttpImpl' ) }, + /** + * Parse given URL + * + * If the URL begins with a slash, the origin is prepended. + * + * @param {string} url URL + * + * @return {Object} parsed URL + */ + 'private _parseUrl'( url ) + { + const origin = ( url[ 0 ] === '/' ) + ? this._origin + : ''; + + return this._urlParser.parse( origin + url ); + }, + + /** * Set request options * diff --git a/test/dapi/http/NodeHttpImplTest.js b/test/dapi/http/NodeHttpImplTest.js index 96a4195..72ba65a 100644 --- a/test/dapi/http/NodeHttpImplTest.js +++ b/test/dapi/http/NodeHttpImplTest.js @@ -90,6 +90,53 @@ describe( "NodeHttpImpl", () => } ); + describe( "given an origin", () => + { + it( "prepends to URL if URL begins with a slash", done => + { + const origin = 'https://foo.com'; + const path = '/quux/quuux'; + + const url = _createMockUrl( given_url => + { + expect( given_url ).to.equal( origin + path ); + done(); + } ); + + const http = _createMockHttp( ( _, callback ) => + { + callback( res ); + res.trigger( 'end' ); + } ); + + Sut( { http: http }, url, origin ) + .requestData( path, 'GET', {}, () => {} ); + } ); + + + it( "does not prepend to URL that does not begin with a slash", done => + { + const origin = 'https://bar.com'; + const path = 'http://foo.com/quux/quuux'; + + const url = _createMockUrl( given_url => + { + expect( given_url ).to.equal( path ); + done(); + } ); + + const http = _createMockHttp( ( _, callback ) => + { + callback( res ); + res.trigger( 'end' ); + } ); + + Sut( { http: http }, url, origin ) + .requestData( path, 'GET', {}, () => {} ); + } ); + } ); + + it( "returns response when no error", done => { const res = _createMockResp();