Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Buzz resource fix #284

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/Angular.js
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,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
Expand Down
13 changes: 7 additions & 6 deletions src/Resource.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(/\/*$/, '');
Expand Down
20 changes: 20 additions & 0 deletions test/AngularSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,26 @@ describe('toKeyValue', 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() {
Expand Down
13 changes: 12 additions & 1 deletion test/ResourceSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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});
Expand Down