aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Angular.js17
-rw-r--r--src/Resource.js13
-rw-r--r--test/AngularSpec.js22
-rw-r--r--test/ResourceSpec.js13
4 files changed, 58 insertions, 7 deletions
diff --git a/src/Angular.js b/src/Angular.js
index 6e5786ec..2d4b1671 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -853,6 +853,23 @@ function toKeyValue(obj) {
return parts.length ? parts.join('&') : '';
}
+
+/**
+ * we need our custom mehtod because encodeURIComponent is too agressive and doesn't follow
+ * http://www.ietf.org/rfc/rfc2396.txt with regards to the character set (pchar) allowed in path
+ * segments
+ */
+function encodeUriSegment(val) {
+ return encodeURIComponent(val).
+ replace(/%40/gi, '@').
+ replace(/%3A/gi, ':').
+ replace(/%26/gi, '&').
+ replace(/%3D/gi, '=').
+ replace(/%2B/gi, '+').
+ replace(/%24/g, '$').
+ replace(/%2C/gi, ',');
+}
+
/**
* @workInProgress
* @ngdoc directive
diff --git a/src/Resource.js b/src/Resource.js
index e801d200..f748fb5a 100644
--- a/src/Resource.js
+++ b/src/Resource.js
@@ -13,19 +13,20 @@ function Route(template, defaults) {
Route.prototype = {
url: function(params) {
- var path = [];
- var self = this;
- var url = this.template;
+ var self = this,
+ url = this.template,
+ encodedVal;
+
params = params || {};
forEach(this.urlParams, function(_, urlParam){
- var value = params[urlParam] || self.defaults[urlParam] || "";
- url = url.replace(new RegExp(":" + urlParam + "(\\W)"), encodeURIComponent(value) + "$1");
+ encodedVal = encodeUriSegment(params[urlParam] || self.defaults[urlParam] || "")
+ url = url.replace(new RegExp(":" + urlParam + "(\\W)"), encodedVal + "$1");
});
url = url.replace(/\/?#$/, '');
var query = [];
forEachSorted(params, function(value, key){
if (!self.urlParams[key]) {
- query.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
+ query.push(encodeUriSegment(key) + '=' + encodeUriSegment(value));
}
});
url = url.replace(/\/*$/, '');
diff --git a/test/AngularSpec.js b/test/AngularSpec.js
index 8753d887..5b7e33fd 100644
--- a/test/AngularSpec.js
+++ b/test/AngularSpec.js
@@ -139,6 +139,28 @@ describe('angular', function(){
});
+ describe('encodeUriSegment', function() {
+ it('should correctly encode uri segment and not encode chars defined as pchar set in rfc2396',
+ function() {
+ //don't encode alphanum
+ expect(encodeUriSegment('asdf1234asdf')).
+ toEqual('asdf1234asdf');
+
+ //don't encode unreserved'
+ expect(encodeUriSegment("-_.!~*'() -_.!~*'()")).
+ toEqual("-_.!~*'()%20-_.!~*'()");
+
+ //don't encode the rest of pchar'
+ expect(encodeUriSegment(':@&=+$, :@&=+$,')).
+ toEqual(':@&=+$,%20:@&=+$,');
+
+ //encode '/', ';' and ' ''
+ expect(encodeUriSegment('/; /;')).
+ toEqual('%2F%3B%20%2F%3B');
+ });
+ });
+
+
describe ('rngScript', function() {
it('should match angular.js', function() {
expect('angular.js'.match(rngScript)).not.toBeNull();
diff --git a/test/ResourceSpec.js b/test/ResourceSpec.js
index adc93b92..c93bdafb 100644
--- a/test/ResourceSpec.js
+++ b/test/ResourceSpec.js
@@ -43,11 +43,22 @@ describe("resource", function() {
it('should correctly encode url params', function(){
var R = resource.route('/Path/:a');
xhr.expectGET('/Path/foo%231').respond({});
- xhr.expectGET('/Path/doh!%40foo?bar=baz%231').respond({});
+ xhr.expectGET('/Path/doh!@foo?bar=baz%231').respond({});
R.get({a: 'foo#1'});
R.get({a: 'doh!@foo', bar: 'baz#1'});
});
+ it('should not encode @ in url params', function() {
+ //encodeURIComponent is too agressive and doesn't follow http://www.ietf.org/rfc/rfc2396.txt
+ //with regards to the character set (pchar) allowed in path segments
+ //so we need this test to make sure that we don't over-encode the params and break stuff like
+ //buzz api which uses @self
+
+ var R = resource.route('/Path/:a');
+ xhr.expectGET('/Path/doh@foo?bar=baz@1').respond({});
+ R.get({a: 'doh@foo', bar: 'baz@1'});
+ })
+
it("should build resource with default param", function(){
xhr.expectGET('/Order/123/Line/456.visa?minimum=0.05').respond({id:'abc'});
var LineItem = resource.route('/Order/:orderId/Line/:id:verb', {orderId: '123', id: '@id.key', verb:'.visa', minimum:0.05});