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

Commit e34ad60

Browse files
committed
WIP
1 parent 460d63d commit e34ad60

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

src/ngResource/resource.js

+100
Original file line numberDiff line numberDiff line change
@@ -529,13 +529,113 @@ angular.module('ngResource', ['ng']).
529529
encodeUriQuery = angular.$$encodeUriQuery,
530530
encodeUriSegment = angular.$$encodeUriSegment;
531531

532+
var urlTransforms = [];
533+
532534
function Route(template, defaults) {
533535
this.template = template;
534536
this.defaults = extend({}, provider.defaults, defaults);
535537
this.urlParams = {};
536538
}
537539

538540
Route.prototype = {
541+
extractParams: function(str) {
542+
if (!str || !str.length) {
543+
return str;
544+
}
545+
546+
var extracted = {
547+
parts: [],
548+
params: [],
549+
paramsPositions: []
550+
};
551+
var escaped = false;
552+
var inParam = false;
553+
var buffer = [];
554+
555+
str.split('').forEach(function(char) {
556+
if (inParam && /\W/.test(char)) {
557+
paramsPositions.push(parts.length);
558+
params.push(buffer.join(''));
559+
parts.push(null);
560+
561+
buffer.length = 0;
562+
inParam = false;
563+
}
564+
565+
if (char === '\\') {
566+
if (escaped) {
567+
buffer.push(char);
568+
} else {
569+
escaped = true;
570+
}
571+
} else if (char === ':') {
572+
if (escaped) {
573+
buffer.push(char);
574+
} else {
575+
parts.push(buffer.join(''));
576+
577+
buffer.length = 0;
578+
inParam = true;
579+
}
580+
581+
escaped = false;
582+
} else {
583+
buffer.push(char);
584+
escaped = false;
585+
}
586+
});
587+
588+
if (inParam) {
589+
paramsPositions.push(parts.length);
590+
params.push(buffer.join(''));
591+
parts.push(null);
592+
} else {
593+
parts.push(buffer.join(''));
594+
}
595+
596+
return extracted;
597+
},
598+
599+
parseUrl: function(url) {
600+
var PROTOCOL_SERVER_REST_REGEX = /^(https?):\/\/([^/]*)(.*)$/;
601+
var USERINFO_HOST_PORT_REGEX = /^(?:([^@]*)@)?(.*?)(?::(\d+))?$/;
602+
var PATH_QUERY_REGEX = /^([^?]*)(?:\?(.*))?$/;
603+
604+
var self = this;
605+
var parsedUrl = {};
606+
var match;
607+
608+
match = PROTOCOL_SERVER_REST_REGEX.exec(url);
609+
610+
parsedUrl.protocol = match[1]; // No params in protocol
611+
var userInfoHostPort = match[2];
612+
var pathQuery = match[3];
613+
614+
match = USERINFO_HOST_PORT_REGEX.exec(userInfoHostPort);
615+
616+
parsedUrl.userInfo = match[1]; // No params in userInfo
617+
parsedUrl.host = self.extractParams(match[2]);
618+
parsedUrl.port = match[3]; // No params in port
619+
620+
match = PATH_QUERY_REGEX.exec(pathQuery);
621+
622+
parsedUrl.path = self.extractParams(match[1]);
623+
parsedUrl.query = self.extractParams(match[2]);
624+
625+
return parsedUrl;
626+
},
627+
628+
setUrlParams2: function(config, params, actionUrl) {
629+
var self = this;
630+
var url = actionUrl || self.template;
631+
var parsedUrl = self.parseUrl(url);
632+
params = params || {};
633+
634+
urlTransforms.forEach(function(transform) {
635+
transform(self, parsedUrl, params);
636+
});
637+
},
638+
539639
setUrlParams: function(config, params, actionUrl) {
540640
var self = this,
541641
url = actionUrl || self.template,

test/ngResource/resourceSpec.js

+30
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,13 @@ describe('basic usage', function() {
240240
R.get({a: 'foo', b: 'bar'});
241241
});
242242

243+
fit('should support escaped and unescaped params with the same name', function() {
244+
var R = $resource('http://localhost\\:8080/Path/:a/\\:b/:c/:b');
245+
246+
$httpBackend.expect('GET', 'http://localhost:8080/Path/foo/:b/baz/bar').respond();
247+
R.get({a: 'foo', b: 'bar', c: 'baz'});
248+
});
249+
243250
it('should support an unescaped url', function() {
244251
var R = $resource('http://localhost:8080/Path/:a');
245252

@@ -368,6 +375,29 @@ describe('basic usage', function() {
368375
R6.get({octet: 42});
369376
});
370377

378+
fit('should support setting `hostname` to IPv6 URL via param', inject(function($q) {
379+
var keepSlashes = {stripTrailingSlashes: false};
380+
381+
var R1 = $resource('http://:host', null, null, keepSlashes);
382+
var R2 = $resource('http://:host/', null, null, keepSlashes);
383+
var R3 = $resource('http://:hostname::port', null, null, keepSlashes);
384+
var R4 = $resource('http://:hostname::port/', null, null, keepSlashes);
385+
386+
$httpBackend.expect('GET', 'http://[2620:0:861:ed1a::1]').respond(null); // R1
387+
$httpBackend.expect('GET', 'http://[2620:0:861:ed1a::1]:1337').respond(null); // R1
388+
$httpBackend.expect('GET', 'http://[2620:0:861:ed1a::1]/').respond(null); // R2
389+
$httpBackend.expect('GET', 'http://[2620:0:861:ed1a::1]:1337/').respond(null); // R2
390+
$httpBackend.expect('GET', 'http://[2620:0:861:ed1a::1]:1337').respond(null); // R3
391+
$httpBackend.expect('GET', 'http://[2620:0:861:ed1a::1]:1337/').respond(null); // R4
392+
393+
R1.get({host: '[2620:0:861:ed1a::1]'});
394+
R1.get({host: '[2620:0:861:ed1a::1]:1337'});
395+
R2.get({host: '[2620:0:861:ed1a::1]'});
396+
R2.get({host: '[2620:0:861:ed1a::1]:1337'});
397+
R3.get({hostname: '[2620:0:861:ed1a::1]', port: '1337'});
398+
R4.get({hostname: '[2620:0:861:ed1a::1]', port: '1337'});
399+
}));
400+
371401
it('should support overriding provider default trailing-slash stripping configuration', function() {
372402
// Set the new behavior for all new resources created by overriding the
373403
// provider configuration

0 commit comments

Comments
 (0)