Skip to content

Commit d302d34

Browse files
committed
Exclude default ports 80/443 from base URL
Fix #59.
1 parent 34f3a96 commit d302d34

File tree

4 files changed

+141
-1
lines changed

4 files changed

+141
-1
lines changed

oauth-1.0a.d.ts

+23
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ declare class OAuth {
1717
signature_metho: string;
1818
version: string;
1919

20+
static urlPattern: RegExp;
21+
22+
/**
23+
* Parse an URL into its various component.
24+
*
25+
* Does no normalisation but throw if it encounters non-ascii char or if the
26+
* URL does represent a http(s) request.
27+
*/
28+
static parseUrl(url: string): OAuth.URL;
29+
2030
constructor(opts?: OAuth.Options);
2131

2232
/**
@@ -189,4 +199,17 @@ declare namespace OAuth {
189199
secret: string;
190200
}
191201

202+
/**
203+
* URL components
204+
*/
205+
export interface URL {
206+
auth: string;
207+
hash: string;
208+
hostname: string;
209+
pathname: string;
210+
port: string;
211+
protocol: 'http' | 'https';
212+
search: string;
213+
}
214+
192215
}

oauth-1.0a.js

+43-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,37 @@ function OAuth(opts) {
4848
this.body_hash_function = opts.body_hash_function || this.hash_function;
4949
}
5050

51+
// Static methods and properties.
52+
Object.defineProperties(OAuth, {
53+
54+
// cache the url regexp.
55+
urlPattern: {
56+
value: /^(https?):\/\/([^:]+:[^@]+@)?([^:/?#]+)(\:\d+)?(\/[^?#]*)?(\?[^#]*)?(#.*)?$/
57+
},
58+
59+
// Parse url into components.
60+
parseUrl: {
61+
value: function(url) {
62+
var match = OAuth.urlPattern.exec(url);
63+
var components;
64+
65+
if (match == null || match.len < 8) {
66+
throw new Error('Invalid URL: "' + url + '".');
67+
}
68+
69+
return {
70+
protocol: match[1],
71+
auth: match[2] || '',
72+
hostname: match[3],
73+
port: match[4] || '',
74+
pathname: match[5] || '',
75+
search: match[6] || '',
76+
hash: match[7] || ''
77+
};
78+
}
79+
}
80+
});
81+
5182
/**
5283
* OAuth request authorize
5384
* @param {Object} request data
@@ -194,7 +225,18 @@ OAuth.prototype.getSigningKey = function(token_secret) {
194225
* @return {String}
195226
*/
196227
OAuth.prototype.getBaseUrl = function(url) {
197-
return url.split('?')[0];
228+
var parsed = OAuth.parseUrl(url);
229+
var port = parsed.port;
230+
var protocol = parsed.protocol.toLowerCase();
231+
232+
if (
233+
(port === ':80' && protocol === 'http') ||
234+
(port === ':443' && protocol === 'https')
235+
) {
236+
parsed.port = '';
237+
}
238+
239+
return parsed.protocol + '://' + parsed.auth + parsed.hostname + parsed.port + parsed.pathname;
198240
};
199241

200242
/**

test/getBaseUrl.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
var expect = require('chai').expect;
2+
var OAuth = require('../oauth-1.0a');
3+
4+
describe('#getBaseUrl', function() {
5+
var oauth = new OAuth({consumer: {}});
6+
7+
beforeEach(function () {
8+
oauth = new OAuth({consumer: {}});
9+
});
10+
11+
it('should return base url', function () {
12+
expect(oauth.getBaseUrl('http://example.com/path/')).to.equal('http://example.com/path/');
13+
expect(oauth.getBaseUrl('http://example.com/path/?foo=bar')).to.equal('http://example.com/path/');
14+
});
15+
16+
it('should exclude default port number', function () {
17+
expect(oauth.getBaseUrl('http://example.com/')).to.equal('http://example.com/');
18+
expect(oauth.getBaseUrl('http://example.com:80/')).to.equal('http://example.com/');
19+
expect(oauth.getBaseUrl('https://example.com/')).to.equal('https://example.com/');
20+
expect(oauth.getBaseUrl('https://example.com:443/')).to.equal('https://example.com/');
21+
});
22+
23+
it('should include non-default port number', function () {
24+
expect(oauth.getBaseUrl('http://example.com:8080/')).to.equal('http://example.com:8080/');
25+
expect(oauth.getBaseUrl('http://example.com:443/')).to.equal('http://example.com:443/');
26+
expect(oauth.getBaseUrl('https://example.com:8080/')).to.equal('https://example.com:8080/');
27+
expect(oauth.getBaseUrl('https://example.com:80/')).to.equal('https://example.com:80/');
28+
});
29+
});

test/parseUrl.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
var expect = require('chai').expect;
2+
var OAuth = require('../oauth-1.0a');
3+
4+
describe('OAuth.parseUrl', function() {
5+
6+
it('should parse protocol', function () {
7+
expect(OAuth.parseUrl('http://example.com/').protocol).to.equal('http');
8+
expect(OAuth.parseUrl('https://example.com/').protocol).to.equal('https');
9+
});
10+
11+
it('should parse auth component', function () {
12+
expect(OAuth.parseUrl('http://example.com/').auth).to.equal('');
13+
expect(OAuth.parseUrl('http://foo:[email protected]/').auth).to.equal('foo:bar@');
14+
});
15+
16+
it('should parse hostname component', function () {
17+
expect(OAuth.parseUrl('http://example.com/').hostname).to.equal('example.com');
18+
expect(OAuth.parseUrl('http://example.com:8080/').hostname).to.equal('example.com');
19+
expect(OAuth.parseUrl('http://foo:[email protected]/').hostname).to.equal('example.com');
20+
});
21+
22+
it('should parse port component', function () {
23+
expect(OAuth.parseUrl('http://example.com/').port).to.equal('');
24+
expect(OAuth.parseUrl('http://example.com:80/').port).to.equal(':80');
25+
expect(OAuth.parseUrl('http://foo:[email protected]:80/').port).to.equal(':80');
26+
});
27+
28+
it('should parse pathname component', function () {
29+
expect(OAuth.parseUrl('http://example.com').pathname).to.equal('');
30+
expect(OAuth.parseUrl('http://example.com/').pathname).to.equal('/');
31+
expect(OAuth.parseUrl('http://example.com/foo/bar').pathname).to.equal('/foo/bar');
32+
});
33+
34+
it('should parse search component', function () {
35+
expect(OAuth.parseUrl('http://example.com').search).to.equal('');
36+
expect(OAuth.parseUrl('http://example.com/?foo').search).to.equal('?foo');
37+
expect(OAuth.parseUrl('http://example.com/?foo#bar').search).to.equal('?foo');
38+
expect(OAuth.parseUrl('http://example.com/?foo?bar').search).to.equal('?foo?bar');
39+
});
40+
41+
it('should parse hash component', function () {
42+
expect(OAuth.parseUrl('http://example.com').hash).to.equal('');
43+
expect(OAuth.parseUrl('http://example.com/?foo').hash).to.equal('');
44+
expect(OAuth.parseUrl('http://example.com/?foo#bar').hash).to.equal('#bar');
45+
});
46+
});

0 commit comments

Comments
 (0)