From 95fb2756e9bdcafdc248957a79686f79db94f228 Mon Sep 17 00:00:00 2001 From: Connor Bode Date: Mon, 23 Jun 2014 02:00:30 -0400 Subject: [PATCH] option to disable encoding slashes for url params fixes #1388 --- src/ngResource/resource.js | 16 ++++++++----- test/ngResource/resourceSpec.js | 40 ++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/ngResource/resource.js b/src/ngResource/resource.js index 74c1c07356b6..999809c4b5c9 100644 --- a/src/ngResource/resource.js +++ b/src/ngResource/resource.js @@ -155,12 +155,14 @@ function shallowClearAndCopy(src, dst) { * with `http response` object. See {@link ng.$http $http interceptors}. * * @param {Object} options Hash with custom settings that should extend the - * default `$resourceProvider` behavior. The only supported option is + * default `$resourceProvider` behavior. * * Where: * * - **`stripTrailingSlashes`** – {boolean} – If true then the trailing * slashes from any calculated URL will be stripped. (Defaults to true.) + * - **`encodeSlashes`** - {boolean} - If true then slashes in URL parameters + * will be encoded. (Defaults to true.) * * @returns {Object} A resource "class" object with methods for the default set of resource actions * optionally extended with custom `actions`. The default set contains these actions: @@ -344,6 +346,9 @@ angular.module('ngResource', ['ng']). // Strip slashes by default stripTrailingSlashes: true, + // Encode slashes by default + encodeSlashes: true, + // Default actions configuration actions: { 'get': {method: 'GET'}, @@ -373,8 +378,8 @@ angular.module('ngResource', ['ng']). * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" * / "*" / "+" / "," / ";" / "=" */ - function encodeUriSegment(val) { - return encodeUriQuery(val, true). + function encodeUriSegment(val, encodeSlashes) { + return encodeUriQuery(val, true, encodeSlashes). replace(/%26/gi, '&'). replace(/%3D/gi, '='). replace(/%2B/gi, '+'); @@ -392,12 +397,13 @@ angular.module('ngResource', ['ng']). * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" * / "*" / "+" / "," / ";" / "=" */ - function encodeUriQuery(val, pctEncodeSpaces) { + function encodeUriQuery(val, pctEncodeSpaces, encodeSlashes) { return encodeURIComponent(val). replace(/%40/gi, '@'). replace(/%3A/gi, ':'). replace(/%24/g, '$'). replace(/%2C/gi, ','). + replace(/%2F/g, (encodeSlashes ? '%2F' : '/')). replace(/%20/g, (pctEncodeSpaces ? '%20' : '+')); } @@ -430,7 +436,7 @@ angular.module('ngResource', ['ng']). forEach(self.urlParams, function (_, urlParam) { val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam]; if (angular.isDefined(val) && val !== null) { - encodedVal = encodeUriSegment(val); + encodedVal = encodeUriSegment(val, self.defaults.encodeSlashes); url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function (match, p1) { return encodedVal + p1; }); diff --git a/test/ngResource/resourceSpec.js b/test/ngResource/resourceSpec.js index 6e58976355bd..ea54c9fd3a2f 100644 --- a/test/ngResource/resourceSpec.js +++ b/test/ngResource/resourceSpec.js @@ -293,7 +293,7 @@ describe("resource", function() { }); it('should support overriding provider default trailing-slash stripping configuration', function() { - // Set the new behavior for all new resources created by overriding the + // Set the new behav ior for all new resources created by overriding the // provider configuration resourceProvider.defaults.stripTrailingSlashes = false; @@ -304,6 +304,44 @@ describe("resource", function() { R.get({a: 'foo'}); }); + it('should support implicitly encode slashes in urls', function () { + var R = $resource('http://localhost:8080/:path'); + + $httpBackend.expect('GET', 'http://localhost:8080/Foo%2Fbar').respond(); + R.get({path: 'Foo/bar'}); + }); + + it('should support explicitly encoding slashes in urls', function () { + var R = $resource('http://localhost:8080/:path', {}, {}, {encodeSlashes: true}); + + $httpBackend.expect('GET', 'http://localhost:8080/Foo%2Fbar').respond(); + R.get({path: 'Foo/bar'}); + }); + + it('should support explicitly preventing encoding slashes in urls', function () { + var R = $resource('http://localhost:8080/:path', {}, {}, {encodeSlashes: false}); + + $httpBackend.expect('GET', 'http://localhost:8080/Foo/bar').respond(); + R.get({path: 'Foo/bar'}); + }); + + it('should support provider-level configuration to prevent encoding slashes in urls', function () { + resourceProvider.defaults.encodeSlashes = false; + + var R = $resource('http://localhost:8080/:path'); + + $httpBackend.expect('GET', 'http://localhost:8080/Foo/bar').respond(); + R.get({path: 'Foo/bar'}); + }); + + it('should support overriding provider default prevent encoding slashes configuration', function () { + resourceProvider.defaults.encodeSlashes = false; + + var R = $resource('http://localhost:8080/:path', {}, {}, {encodeSlashes: true}); + + $httpBackend.expect('GET', 'http://localhost:8080/Foo%2Fbar').respond(); + R.get({path: 'Foo/bar'}); + }); it('should allow relative paths in resource url', function () { var R = $resource(':relativePath');