From 9e0b10f3142ab75dde0c3a0bd24b263c16f32692 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 12 Jan 2017 12:40:31 -0800 Subject: [PATCH] http: path parsing. --- lib/http/base.js | 61 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/lib/http/base.js b/lib/http/base.js index 6fce6847..0254344c 100644 --- a/lib/http/base.js +++ b/lib/http/base.js @@ -114,9 +114,13 @@ HTTPBase.prototype._initRouter = function _initRouter() { */ HTTPBase.prototype.handleRequest = co(function* handleRequest(req, res) { + var url = initRequest(req, res, this.keyLimit); var i, routes, route, params; - initRequest(req, res, this.keyLimit); + if (url.trailingSlash) { + res.redirect(302, req.url); + return; + } this.emit('request', req, res); @@ -587,6 +591,8 @@ Routes.prototype.getHandlers = function getHandlers(method) { function nop() {} function initRequest(req, res, limit) { + var url; + req.on('error', nop); assert(req.contentType == null); @@ -618,12 +624,21 @@ function initRequest(req, res, limit) { assert(res.sent == null); assert(res.send == null); assert(res.error == null); + assert(res.redirect == null); res.sent = false; res.send = makeSend(res); res.error = makeSendError(req, res); + res.redirect = makeRedirect(res); - parsePath(req, limit); + url = parseURL(req.url, limit); + + req.url = url.url; + req.pathname = url.pathname; + req.path = url.path; + req.query = url.query; + + return url; } function makeSend(res) { @@ -714,6 +729,18 @@ function sendError(req, res, err) { } } +function makeRedirect(res) { + return function redirect(code, url) { + if (!url) { + url = code; + code = 302; + } + res.statusCode = code; + res.setHeader('Location', url); + res.end(); + }; +} + function parsePairs(str, limit) { var parts = str.split('&'); var data = Object.create(null); @@ -749,10 +776,12 @@ function parsePairs(str, limit) { return data; } -function parsePath(req, limit) { - var uri = URL.parse(req.url); +function parseURL(reqUrl, limit) { + var uri = URL.parse(reqUrl); + var parsed = new ParsedURL(reqUrl); var pathname = uri.pathname; var query = Object.create(null); + var trailing = false; var path, parts, url; if (pathname) { @@ -762,8 +791,10 @@ function parsePath(req, limit) { pathname = '/' + pathname; if (pathname.length > 1) { - if (pathname[pathname.length - 1] === '/') + if (pathname[pathname.length - 1] === '/') { pathname = pathname.slice(0, -1); + trailing = true; + } } pathname = unescape(pathname); @@ -804,10 +835,22 @@ function parsePath(req, limit) { if (uri.query) query = parsePairs(uri.query, limit); - req.url = url; - req.pathname = pathname; - req.path = parts; - req.query = query; + parsed.url = url; + parsed.pathname = pathname; + parsed.path = path; + parsed.query = query; + parsed.trailingSlash = trailing; + + return parsed; +} + +function ParsedURL(original) { + this.original = original; + this.url = null; + this.pathname = null; + this.path = null; + this.query = null; + this.trailingSlash = false; } function unescape(str) {