From 13d20006439f192293bc918c5845dd3cafcf92dd Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 6 Jul 2017 03:00:25 +0200 Subject: [PATCH] Initialize parseURL and parseQueryString lazily --- http/vibe/http/server.d | 83 +++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/http/vibe/http/server.d b/http/vibe/http/server.d index 08bb9dd7ba..276cae073b 100644 --- a/http/vibe/http/server.d +++ b/http/vibe/http/server.d @@ -475,9 +475,9 @@ alias HTTPServerErrorPageHandler = void delegate(HTTPServerRequest req, HTTPServ */ enum HTTPServerOption { none = 0, - /// Fills the `.path` and `.queryString` fields in the request + /// Deprecated: Fills the `.path` and `.queryString` fields in the request parseURL = 1<<0, - /// Fills the `.query` field in the request + /// Deprecated: Fills the `.query` field in the request parseQueryString = 1<<1 | parseURL, /// Deprecated: Fills the `.form` field in the request parseFormBody = 1<<2, @@ -800,29 +800,51 @@ final class HTTPServerRequest : HTTPRequest { */ TLSCertificateInformation clientCertificate; - /** The _path part of the URL. + private bool urlParsed; + private void parseURL() @safe { + auto url = URL.parse(requestURL); + _path = urlDecode(url.pathString); + _queryString = url.queryString; + _username = url.username; + _password = url.password; + urlParsed = true; + } - Remarks: This field is only set if HTTPServerOption.parseURL is set. + /** The _path part of the URL. */ - string path; + ref string path() @safe { + if (!urlParsed) + parseURL; + return _path; + } + private string _path; /** The user name part of the URL, if present. - - Remarks: This field is only set if HTTPServerOption.parseURL is set. */ - string username; + ref string username() @safe { + if (!urlParsed) + parseURL; + return _username; + } + private string _username; /** The _password part of the URL, if present. - - Remarks: This field is only set if HTTPServerOption.parseURL is set. */ - string password; + ref string password() @safe { + if (!urlParsed) + parseURL; + return _password; + } + private string _password; /** The _query string part of the URL. - - Remarks: This field is only set if HTTPServerOption.parseURL is set. */ - string queryString; + ref string queryString() @safe { + if (!urlParsed) + parseURL; + return _queryString; + } + private string _queryString; /** Contains the list of _cookies that are stored on the client. @@ -846,10 +868,16 @@ final class HTTPServerRequest : HTTPRequest { /** Contains all _form fields supplied using the _query string. The fields are stored in the same order as they are received. - - Remarks: This field is only set if HTTPServerOption.parseQueryString is set. */ - FormFields query; + @property ref const(FormFields) query() @safe { + if (_query.isNull) { + _query = FormFields.init; + parseURLEncodedForm(queryString, _query); + } + + return _query.get; + } + Nullable!FormFields _query; import vibe.utils.dictionarylist; /** A map of general parameters for the request. @@ -977,8 +1005,7 @@ final class HTTPServerRequest : HTTPRequest { Note that the port is currently not set, so that this only works if the standard port is used. */ - @property URL fullURL() - const @safe { + @property URL fullURL() @safe { URL url; auto xfh = this.headers.get("X-Forwarded-Host"); @@ -1046,7 +1073,7 @@ final class HTTPServerRequest : HTTPRequest { The returned string always ends with a slash. */ - @property string rootDir() const @safe { + @property string rootDir() @safe { if (path.length == 0) return "./"; auto depth = count(path[1 .. $], '/'); return depth == 0 ? "./" : replicate("../", depth); @@ -2107,22 +2134,6 @@ private bool handleRequest(InterfaceProxy!Stream http_stream, TCPConnection tcp_ } } - // URL parsing if desired - if (settings.options & HTTPServerOption.parseURL) { - auto url = URL.parse(req.requestURL); - req.path = urlDecode(url.pathString); - req.queryString = url.queryString; - req.username = url.username; - req.password = url.password; - } - - // query string parsing if desired - if (settings.options & HTTPServerOption.parseQueryString) { - if (!(settings.options & HTTPServerOption.parseURL)) - logWarn("Query string parsing requested but URL parsing is disabled!"); - parseURLEncodedForm(req.queryString, req.query); - } - // lookup the session if (settings.sessionStore) { // use the first cookie that contains a valid session ID in case