Skip to content

Commit

Permalink
Fixing Issue #19 - relative scheme URLs
Browse files Browse the repository at this point in the history
  • Loading branch information
rodneyrehm committed Mar 17, 2012
1 parent c1da024 commit 54a475f
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 25 deletions.
12 changes: 10 additions & 2 deletions docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,16 @@ <h3 id="accessors-protocol">protocol(), scheme()</h3>
// get protocol
uri.protocol(); // returns string "http"
// set protocol
uri.protocol("ftp"); // returns the URI instance for chaining</pre>
<p>NOTE: Throws a <code>TypeError</code> on illegal input</p>
uri.protocol("ftp"); // returns the URI instance for chaining

// relative scheme
uri.protocol("");
uri.toString() === '//example.org/foo/hello.html';

// remove scheme
uri.protocol(null);
uri.toString() === 'example.org/foo/hello.html';</pre>
<p>NOTE: Throws a <code>TypeError</code> on illegal input, that is anything but <code>[a-z0-9.+-]</code> and <code>[empty string]</code> and <code>null</code></p>

<h3 id="accessors-username">username()</h3>
<pre class="prettyprint lang-js">var uri = new URI("http://user:pass@example.org/foo/hello.html");
Expand Down
45 changes: 27 additions & 18 deletions src/URI.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,25 @@ URI.parse = function(string) {
}

// extract protocol
pos = string.indexOf(':');
if (pos > -1) {
parts.protocol = string.substring(0, pos);
if (string.substring(pos + 1, pos + 3) === '//') {
string = string.substring(pos + 3);

// extract "user:pass@host:port"
string = URI.parseAuthority(string, parts);
} else {
string = string.substring(pos + 1);
parts.urn = true;
if (string.substring(0, 2) === '//') {
// relative-scheme
parts.protocol = '';
string = string.substring(2);
// extract "user:pass@host:port"
string = URI.parseAuthority(string, parts);
} else {
pos = string.indexOf(':');
if (pos > -1) {
parts.protocol = string.substring(0, pos);
if (string.substring(pos + 1, pos + 3) === '//') {
string = string.substring(pos + 3);

// extract "user:pass@host:port"
string = URI.parseAuthority(string, parts);
} else {
string = string.substring(pos + 1);
parts.urn = true;
}
}
}

Expand Down Expand Up @@ -316,9 +324,10 @@ URI.build = function(parts) {

if (typeof parts.protocol === "string" && parts.protocol.length) {
t += parts.protocol + ":";
if (!parts.urn) {
t += '//';
}
}

if ((t || parts.protocol === '') && !parts.urn) {
t += '//';
}

t += (URI.buildAuthority(parts) || '');
Expand Down Expand Up @@ -705,11 +714,11 @@ var _protocol = p.protocol,

p.protocol = function(v, build) {
if (v !== undefined) {
// accept trailing :
if (v) {
if (v[v.length - 1] === ":") {
v = v.substring(0, v.length - 1);
} else if (v.match(/[^a-zA-z0-9\.+-]/)) {
// accept trailing ://
v = v.replace(/:(\/\/)?$/, '');

if (v.match(/[^a-zA-z0-9\.+-]/)) {
throw new TypeError("Protocol '" + v + "' contains characters other than [A-Z0-9.+-]");
}
}
Expand Down
6 changes: 3 additions & 3 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ test("protocol", function() {
equal(u+"", "ftp://example.org/foo.html", "ftp url");

u.protocol('');
equal(u.protocol(), "", "missing protocol");
equal(u+"", "example.org/foo.html", "no-scheme url");
equal(u.protocol(), "", "relative protocol");
equal(u+"", "//example.org/foo.html", "relative-scheme url");

u.protocol(null);
equal(u.protocol(), "", "missing protocol");
equal(u+"", "example.org/foo.html", "no-scheme url");
equal(u+"", "example.org/foo.html", "missing-scheme url");
});
test("username", function() {
var u = new URI("http://example.org/foo.html");
Expand Down
50 changes: 48 additions & 2 deletions test/urls.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,9 @@ var urls = [{
}, {
name: 'ignoring scheme',
url: '://user:pass@example.org:123/some/directory/file.html?query=string#fragment',
_url: 'user:pass@example.org:123/some/directory/file.html?query=string#fragment',
_url: '//user:pass@example.org:123/some/directory/file.html?query=string#fragment',
parts: {
protocol: "", // not null
protocol: "",
username: 'user',
password: 'pass',
hostname: 'example.org',
Expand Down Expand Up @@ -415,6 +415,52 @@ var urls = [{
idn: false,
punycode: false
}
}, {
name: 'scheme-relative URL',
url: '//www.example.org/',
parts: {
protocol: '', // not null
username: null,
password: null,
hostname: 'www.example.org',
port: null,
path: '/',
query: null,
fragment: null
},
accessors: {
protocol: '',
username: '',
password: '',
port: '',
path: '/',
query: '',
fragment: '',
authority: 'www.example.org',
userinfo: '',
subdomain: 'www',
domain: 'example.org',
tld: 'org',
directory: '/',
filename: '',
suffix: '',
hash: '',
search: '',
host: 'www.example.org',
hostname: 'www.example.org'
},
is: {
urn: false,
url: true,
relative: false,
name: true,
sld: false,
ip: false,
ip4: false,
ip6: false,
idn: false,
punycode: false
}
}, {
name: 'IPv4',
url: 'http://user:pass@123.123.123.123:123/some/directory/file.html?query=string#fragment',
Expand Down

0 comments on commit 54a475f

Please sign in to comment.