Add fast parse and remove parseurl
This commit is contained in:
parent
bd05c21456
commit
6b27b844ff
4 changed files with 112 additions and 6 deletions
57
lib/fastparse.js
Normal file
57
lib/fastparse.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
const url = require('url');
|
||||
|
||||
/**
|
||||
* Parse the `str` url with fast-path short-cut.
|
||||
*
|
||||
* @param {string} str
|
||||
* @return {Object}
|
||||
* @private
|
||||
*/
|
||||
|
||||
module.exports = function fastparse(str) {
|
||||
if (typeof str !== 'string' || str.charCodeAt(0) !== 0x2f /* / */) {
|
||||
return url.parse(str);
|
||||
}
|
||||
|
||||
let pathname = str;
|
||||
let query = null;
|
||||
let search = null;
|
||||
|
||||
// This takes the regexp from https://github.com/joyent/node/pull/7878
|
||||
// Which is /^(\/[^?#\s]*)(\?[^#\s]*)?$/
|
||||
// And unrolls it into a for loop
|
||||
for (let i = 1; i < str.length; i++) {
|
||||
switch (str.charCodeAt(i)) {
|
||||
case 0x3f: /* ? */
|
||||
if (search === null) {
|
||||
pathname = str.substring(0, i);
|
||||
query = str.substring(i + 1);
|
||||
search = str.substring(i);
|
||||
}
|
||||
break;
|
||||
case 0x09: /* \t */
|
||||
case 0x0a: /* \n */
|
||||
case 0x0c: /* \f */
|
||||
case 0x0d: /* \r */
|
||||
case 0x20: /* */
|
||||
case 0x23: /* # */
|
||||
case 0xa0:
|
||||
case 0xfeff:
|
||||
return url.parse(str);
|
||||
}
|
||||
}
|
||||
|
||||
let parsed = new url.Url();
|
||||
|
||||
parsed.path = str;
|
||||
parsed.href = str;
|
||||
parsed.pathname = pathname;
|
||||
|
||||
if (search !== null) {
|
||||
parsed.query = query;
|
||||
parsed.search = search;
|
||||
}
|
||||
parsed.__raw = str;
|
||||
|
||||
return parsed;
|
||||
};
|
|
@ -8,7 +8,7 @@
|
|||
const URL = require('url').URL;
|
||||
const net = require('net');
|
||||
const stringify = require('url').format;
|
||||
const parse = require('parseurl');
|
||||
const fastparse = require('./fastparse');
|
||||
const qs = require('querystring');
|
||||
const typeis = require('type-is');
|
||||
const fresh = require('fresh');
|
||||
|
@ -139,7 +139,14 @@ module.exports = {
|
|||
*/
|
||||
|
||||
get path() {
|
||||
return parse(this.req).pathname;
|
||||
return this.urlParsed.pathname;
|
||||
},
|
||||
|
||||
get urlParsed() {
|
||||
if (!this.req.__url || this.req.__url.__raw !== this.req.url) {
|
||||
this.req.__url = fastparse(this.req.url);
|
||||
}
|
||||
return this.req.__url;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -150,7 +157,7 @@ module.exports = {
|
|||
*/
|
||||
|
||||
set path(path) {
|
||||
const url = parse(this.req);
|
||||
const url = this.urlParsed;
|
||||
if (url.pathname === path) return;
|
||||
|
||||
url.pathname = path;
|
||||
|
@ -192,7 +199,7 @@ module.exports = {
|
|||
|
||||
get querystring() {
|
||||
if (!this.req) return '';
|
||||
return parse(this.req).query || '';
|
||||
return this.urlParsed.query || '';
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -203,7 +210,7 @@ module.exports = {
|
|||
*/
|
||||
|
||||
set querystring(str) {
|
||||
const url = parse(this.req);
|
||||
const url = this.urlParsed;
|
||||
if (url.search === `?${str}`) return;
|
||||
|
||||
url.search = str;
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
"koa-compose": "^4.1.0",
|
||||
"koa-is-json": "^1.0.0",
|
||||
"on-finished": "^2.3.0",
|
||||
"parseurl": "^1.3.2",
|
||||
"type-is": "^1.6.16",
|
||||
"vary": "^1.1.2"
|
||||
},
|
||||
|
|
43
test/parseurl/fastparse.js
Normal file
43
test/parseurl/fastparse.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
const assert = require('assert');
|
||||
const fastparse = require('../../lib/fastparse');
|
||||
|
||||
const URL_EMPTY_VALUE = null;
|
||||
|
||||
describe('fastparse(url)', () => {
|
||||
it('should parse the requrst URL', () => {
|
||||
let url = fastparse('/foo/bar');
|
||||
assert.strictEqual(url.host, URL_EMPTY_VALUE);
|
||||
assert.strictEqual(url.hostname, URL_EMPTY_VALUE);
|
||||
assert.strictEqual(url.href, '/foo/bar');
|
||||
assert.strictEqual(url.pathname, '/foo/bar');
|
||||
assert.strictEqual(url.port, URL_EMPTY_VALUE);
|
||||
assert.strictEqual(url.query, URL_EMPTY_VALUE);
|
||||
assert.strictEqual(url.search, URL_EMPTY_VALUE);
|
||||
});
|
||||
|
||||
it('should parse with query string', () => {
|
||||
let url = fastparse('/foo/bar?fizz=buzz');
|
||||
assert.strictEqual(url.host, URL_EMPTY_VALUE);
|
||||
assert.strictEqual(url.hostname, URL_EMPTY_VALUE);
|
||||
assert.strictEqual(url.href, '/foo/bar?fizz=buzz');
|
||||
assert.strictEqual(url.pathname, '/foo/bar');
|
||||
assert.strictEqual(url.port, URL_EMPTY_VALUE);
|
||||
assert.strictEqual(url.query, 'fizz=buzz');
|
||||
assert.strictEqual(url.search, '?fizz=buzz');
|
||||
});
|
||||
|
||||
it('should parse a full URL', () => {
|
||||
let url = fastparse('http://localhost:8888/foo/bar');
|
||||
assert.strictEqual(url.host, 'localhost:8888');
|
||||
assert.strictEqual(url.hostname, 'localhost');
|
||||
assert.strictEqual(url.href, 'http://localhost:8888/foo/bar');
|
||||
assert.strictEqual(url.pathname, '/foo/bar');
|
||||
assert.strictEqual(url.port, '8888');
|
||||
assert.strictEqual(url.query, URL_EMPTY_VALUE);
|
||||
assert.strictEqual(url.search, URL_EMPTY_VALUE);
|
||||
});
|
||||
|
||||
it('should not choke on auth-looking URL', () => {
|
||||
assert.strictEqual(fastparse('//todo@txt').pathname, '//todo@txt');
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue