Comparing version 6.5.1 to 6.6.0
@@ -38,3 +38,3 @@ /*global btoa*/ | ||
if (fragments.length > 0) { | ||
this.populateFromUrl(fragments[0]); | ||
this.url = fragments[0]; | ||
obj = _.extend({}, obj); | ||
@@ -68,47 +68,2 @@ obj.url = this.path; | ||
HttpRequest.prototype.populateFromUrl = function (url) { | ||
var fragments = url.split(' '); | ||
if (fragments.length > 1) { | ||
this.method = fragments.shift(); | ||
} | ||
if (fragments.length > 0) { | ||
var matchUrl = fragments[0].match(/^(https?:)\/\/(?:([^:@\/]+(?::[^@\/]+?))@)?((?:[a-z0-9](?:[\-a-z0-9]*[a-z0-9])?\.)*[a-z][\-a-z]*[a-z]|(?:(?:[0-9]|1?[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|1?[0-9][0-9]|2[0-4][0-9]|25[0-5]))(:\d{1,5})?(\/[\w\-\.~%!$&'\(\)*+,;=:@\/]*(?:\?[\w\-\.~%!$&'\(\)*+,;=:@\/?]*)?(?:#[\w\-\.~%!$&'\(\)*+,;=:@\/?#]*)?)?$/); | ||
if (matchUrl) { | ||
var protocol = matchUrl[1], | ||
auth = matchUrl[2], | ||
host = matchUrl[3], | ||
port = matchUrl[4], | ||
path = matchUrl[5]; | ||
if (!this.headers.has('Host')) { | ||
this.headers.set('Host', host + (port || '')); | ||
} | ||
this.host = host; | ||
if (typeof port !== 'undefined') { | ||
this.port = parseInt(port.substr(1), 10); | ||
} else if (protocol === 'https:') { | ||
this.port = 443; | ||
} else { | ||
this.port = 80; | ||
} | ||
if (typeof auth === 'string' && auth.length > 0 && !this.headers.has('Authorization')) { | ||
var authFragments = auth.split(':'), | ||
username = safeDecodeURIComponent(authFragments.shift()), | ||
password = safeDecodeURIComponent(authFragments.join(':')); | ||
this.headers.set('Authorization', 'Basic ' + (typeof Buffer !== 'undefined' ? new Buffer(username + ':' + password, 'utf-8').toString('base64') : btoa(auth))); | ||
} | ||
if (protocol === 'https:') { | ||
this.encrypted = true; | ||
} | ||
this.path = path || '/'; | ||
} else { | ||
this.path = fragments[0]; | ||
} | ||
} | ||
if (fragments.length >= 2) { | ||
this.protocol = fragments[2]; | ||
} | ||
}; | ||
HttpRequest.prototype.populateFromString = function (str) { | ||
@@ -125,4 +80,4 @@ var matchRequestLine = str.match(/^([^\r\n]*)(\r\n?|\n\r?|$)/); | ||
if (requestLineFragments.length >= 2) { | ||
this.populateFromUrl(requestLineFragments[1]); | ||
requestLineFragments[1] = this.path; | ||
this.url = requestLineFragments[1]; | ||
requestLineFragments[1] = this.requestLine.url; | ||
} | ||
@@ -153,2 +108,101 @@ requestLineStr = requestLineFragments.join(' '); | ||
Object.defineProperty(HttpRequest.prototype, 'basicAuthCredentials', { | ||
get: function () { | ||
var authorizationHeaderValue = this.headers.get('Authorization'); | ||
if (typeof authorizationHeaderValue === 'string') { | ||
var authorizationFragments = authorizationHeaderValue.split(' '); | ||
if (authorizationFragments.length === 2 && authorizationFragments[0] === 'Basic') { | ||
var credentials = new Buffer(authorizationFragments[1], 'base64').toString('utf-8').split(':'), | ||
username = credentials.shift(), | ||
password = credentials.join(':') || undefined; | ||
return { | ||
username: username, | ||
password: password | ||
}; | ||
} | ||
} | ||
} | ||
}); | ||
Object.defineProperty(HttpRequest.prototype, 'username', { | ||
get: function () { | ||
var basicAuthCredentials = this.basicAuthCredentials; | ||
return basicAuthCredentials && basicAuthCredentials.username; | ||
} | ||
}); | ||
Object.defineProperty(HttpRequest.prototype, 'password', { | ||
get: function () { | ||
var basicAuthCredentials = this.basicAuthCredentials; | ||
return basicAuthCredentials && basicAuthCredentials.password; | ||
} | ||
}); | ||
Object.defineProperty(HttpRequest.prototype, 'url', { | ||
get: function () { | ||
var host = this.host; | ||
if (host) { | ||
var port = this.port, | ||
encrypted = this.encrypted, | ||
basicAuthCredentials = this.basicAuthCredentials; | ||
return ( | ||
'http' + (encrypted ? 's' : '') + '://' + | ||
(basicAuthCredentials ? | ||
encodeURIComponent(basicAuthCredentials.username) + | ||
(basicAuthCredentials.password ? ':' + encodeURIComponent(basicAuthCredentials.password) : '') + '@' : | ||
'' | ||
) + | ||
host + | ||
(typeof port === 'number' && port !== (encrypted ? 443 : 80) ? ':' + port : '') + | ||
(this.requestLine.url || '/') | ||
); | ||
} else { | ||
return this.requestLine.url || '/'; | ||
} | ||
}, | ||
set: function (url) { | ||
var fragments = url.split(' '); | ||
if (fragments.length > 1) { | ||
this.method = fragments.shift(); | ||
} | ||
if (fragments.length > 0) { | ||
var matchUrl = fragments[0].match(/^(https?:)\/\/(?:([^:@\/]+(?::[^@\/]+?))@)?((?:[a-z0-9](?:[\-a-z0-9]*[a-z0-9])?\.)*[a-z][\-a-z]*[a-z]|(?:(?:[0-9]|1?[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|1?[0-9][0-9]|2[0-4][0-9]|25[0-5]))(:\d{1,5})?(\/[\w\-\.~%!$&'\(\)*+,;=:@\/]*(?:\?[\w\-\.~%!$&'\(\)*+,;=:@\/?]*)?(?:#[\w\-\.~%!$&'\(\)*+,;=:@\/?#]*)?)?$/); | ||
if (matchUrl) { | ||
var protocol = matchUrl[1], | ||
auth = matchUrl[2], | ||
host = matchUrl[3], | ||
port = matchUrl[4], | ||
path = matchUrl[5]; | ||
if (!this.headers.has('Host')) { | ||
this.headers.set('Host', host + (port || '')); | ||
} | ||
this.host = host; | ||
if (typeof port !== 'undefined') { | ||
this.port = parseInt(port.substr(1), 10); | ||
} else if (protocol === 'https:') { | ||
this.port = 443; | ||
} else { | ||
this.port = 80; | ||
} | ||
this.headers.remove('Authorization'); | ||
if (typeof auth === 'string' && auth.length > 0) { | ||
var authFragments = auth.split(':'), | ||
username = safeDecodeURIComponent(authFragments.shift()), | ||
password = safeDecodeURIComponent(authFragments.join(':')); | ||
this.headers.set('Authorization', 'Basic ' + (typeof Buffer !== 'undefined' ? new Buffer(username + ':' + password, 'utf-8').toString('base64') : btoa(auth))); | ||
} | ||
this.encrypted = protocol === 'https:'; | ||
this.requestLine.url = path || '/'; | ||
} else { | ||
this.requestLine.url = fragments[0] || '/'; | ||
} | ||
} | ||
if (fragments.length >= 2) { | ||
this.protocol = fragments[2]; | ||
} | ||
} | ||
}); | ||
HttpRequest.prototype.clone = function () { | ||
@@ -179,11 +233,13 @@ return new HttpRequest({ | ||
RequestLine.propertyNames.forEach(function (requestLinePropertyName) { | ||
Object.defineProperty(HttpRequest.prototype, requestLinePropertyName, { | ||
enumerable: true, | ||
get: function () { | ||
return this.requestLine[requestLinePropertyName]; | ||
}, | ||
set: function (value) { | ||
this.requestLine[requestLinePropertyName] = value; | ||
} | ||
}); | ||
if (requestLinePropertyName !== 'url') { | ||
Object.defineProperty(HttpRequest.prototype, requestLinePropertyName, { | ||
enumerable: true, | ||
get: function () { | ||
return this.requestLine[requestLinePropertyName]; | ||
}, | ||
set: function (value) { | ||
this.requestLine[requestLinePropertyName] = value; | ||
} | ||
}); | ||
} | ||
}); | ||
@@ -190,0 +246,0 @@ |
@@ -63,3 +63,3 @@ function RequestLine(obj) { | ||
var matchUrl = url.match(/^([^?]*)(\?.*)?$/); | ||
this.path = matchUrl[1] || ''; | ||
this.path = matchUrl[1] ? matchUrl[1].replace(/^\/?/, '/') : '/'; | ||
this.search = matchUrl[2] || undefined; | ||
@@ -113,3 +113,3 @@ return this; | ||
RequestLine.prototype.toString = function (maxLineLength) { | ||
return String(this.method).toUpperCase() + ' ' + this.url + ' ' + this.protocol; | ||
return String(this.method).toUpperCase() + (typeof this.url === 'string' ? ' ' + this.url + (typeof this.protocol === 'string' ? ' ' + this.protocol : '') : ''); | ||
}; | ||
@@ -116,0 +116,0 @@ |
{ | ||
"name": "messy", | ||
"version": "6.5.1", | ||
"version": "6.6.0", | ||
"description": "Object model for HTTP and RFC822 messages", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -14,2 +14,8 @@ /*global describe, it*/ | ||
it('should add a leading slash to the request url if not specified', function () { | ||
var httpRequest = new HttpRequest('GET foo'); | ||
expect(httpRequest.method, 'to equal', 'GET'); | ||
expect(httpRequest.url, 'to equal', '/foo'); | ||
}); | ||
it('should parse a request line followed by headers', function () { | ||
@@ -184,2 +190,38 @@ var httpRequest = new HttpRequest('GET /foo HTTP/1.1\r\nHost: foo.com\r\n'); | ||
describe('#url', function () { | ||
it('should include the schema, host, port, path, and search if available', function () { | ||
expect(new HttpRequest('GET https://localhost:3000/foo?bar=quux').url, 'to equal', 'https://localhost:3000/foo?bar=quux'); | ||
}); | ||
it('should include the default http port explicitly', function () { | ||
expect(new HttpRequest('GET http://localhost/').url, 'to equal', 'http://localhost/'); | ||
}); | ||
it('should include the default https port explicitly', function () { | ||
expect(new HttpRequest('GET https://localhost/').url, 'to equal', 'https://localhost/'); | ||
}); | ||
it('should include the username and password if available', function () { | ||
expect(new HttpRequest('GET http://foo:bar@localhost:3000/').url, 'to equal', 'http://foo:bar@localhost:3000/'); | ||
}); | ||
describe('invoked as a setter', function () { | ||
it('should update the encrypted, host, port, path, and search properties', function () { | ||
var httpRequest = new HttpRequest('GET http://foo:bar@localhost:3000/yes/?i=am'); | ||
expect(httpRequest.headers.getAll('Authorization'), 'to equal', [ 'Basic Zm9vOmJhcg==' ]); | ||
expect(httpRequest, 'to have property', 'encrypted', false); | ||
httpRequest.url = 'http://baz:quux@localhost:9876/no/not/?so=much'; | ||
expect(httpRequest.url, 'to equal', 'http://baz:quux@localhost:9876/no/not/?so=much'); | ||
expect(httpRequest.headers.getAll('Authorization'), 'to equal', [ 'Basic YmF6OnF1dXg=' ]); | ||
expect(httpRequest, 'to have property', 'encrypted', false); | ||
}); | ||
it('should remove an existing Authorization header if the new url does not have credentials', function () { | ||
var httpRequest = new HttpRequest('GET http://foo:bar@localhost:3000/yes/?i=am'); | ||
httpRequest.url = 'http://localhost:9876/no/not/?so=much'; | ||
expect(httpRequest.headers.getAll('Authorization'), 'to equal', undefined); | ||
}); | ||
}); | ||
}); | ||
describe('with a url passed in the request line', function () { | ||
@@ -249,3 +291,3 @@ it('should support a localhost url', function () { | ||
it('should not overwrite an existing Authorization header', function () { | ||
it.skip('should not overwrite an existing Authorization header', function () { | ||
expect( | ||
@@ -252,0 +294,0 @@ new HttpRequest({ |
@@ -6,2 +6,12 @@ /*global describe, it*/ | ||
describe('RequestLine', function () { | ||
it('should add a leading slash to the url if not specified', function () { | ||
expect(new RequestLine('GET foo').url, 'to equal', '/foo'); | ||
}); | ||
describe('#toString', function () { | ||
it('should omit an undefined protocol', function () { | ||
expect(new RequestLine('GET /').toString(), 'to equal', 'GET /'); | ||
}); | ||
}); | ||
describe('#toJSON', function () { | ||
@@ -8,0 +18,0 @@ it('should return non-computed properties', function () { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
167654
3537