diff --git a/beast/http/HTTP.unity.cpp b/beast/http/HTTP.unity.cpp index 92072fe3ae..405b219bab 100644 --- a/beast/http/HTTP.unity.cpp +++ b/beast/http/HTTP.unity.cpp @@ -25,14 +25,13 @@ #include #include #include -#include #include #include #include #include #include -#include #include +#include #include diff --git a/beast/http/ParsedURL.h b/beast/http/ParsedURL.h deleted file mode 100644 index a2ba305e3a..0000000000 --- a/beast/http/ParsedURL.h +++ /dev/null @@ -1,51 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef BEAST_HTTP_PARSEDURL_H_INCLUDED -#define BEAST_HTTP_PARSEDURL_H_INCLUDED - -#include -#include - -namespace beast { - -/** Parses a String containing a URL. */ -class ParsedURL -{ -public: - ParsedURL (); - explicit ParsedURL (String const& url); - ParsedURL (int error, URL const& url); - ParsedURL (ParsedURL const& other); - ParsedURL& operator= (ParsedURL const& other); - - /** Zero for success, else a non zero value indicating failure. */ - int error () const; - - /** The parsed URL if there was no error. */ - URL url () const; - -private: - int m_error; - URL m_url; -}; - -} - -#endif diff --git a/beast/http/URL.h b/beast/http/URL.h index 7b2b876ec1..7037c5e3e6 100644 --- a/beast/http/URL.h +++ b/beast/http/URL.h @@ -20,8 +20,6 @@ #ifndef BEAST_HTTP_URL_H_INCLUDED #define BEAST_HTTP_URL_H_INCLUDED -#include - #include namespace beast { @@ -32,94 +30,137 @@ namespace beast { class URL { public: - /** Construct an empty URL. */ - explicit URL (); - /** Construct a URL from it's components. */ URL ( - String schema_, - String host_, + std::string schema_, + std::string host_, std::uint16_t port_, - String port_string_, - String path_, - String query_ = "", - String fragment_ = "", - String userinfo_ = ""); + std::string port_string_, + std::string path_, + std::string query_ = "", + std::string fragment_ = "", + std::string userinfo_ = ""); + + /** Construct an empty URL. */ + explicit URL () = default; /** Copy construct a URL. */ - URL (URL const& other); + URL (URL const& other) = default; /** Copy assign a URL. */ - URL& operator= (URL const& other); + URL& operator= (URL const& other) = default; + + /** Move construct a URL. */ + URL (URL&& other) = default; /** Returns `true` if this is an empty URL. */ - bool empty () const; + bool + empty () const; /** Returns the scheme of the URL. If no scheme was specified, the string will be empty. */ - String scheme () const; + std::string const& + scheme () const; /** Returns the host of the URL. If no host was specified, the string will be empty. */ - String host () const; + std::string const& + host () const; /** Returns the port number as an integer. If no port was specified, the value will be zero. */ - std::uint16_t port () const; + std::uint16_t + port () const; /** Returns the port number as a string. If no port was specified, the string will be empty. */ - String port_string () const; + std::string const& + port_string () const; /** Returns the path of the URL. If no path was specified, the string will be empty. */ - String path () const; + std::string const& + path () const; /** Returns the query parameters portion of the URL. If no query parameters were present, the string will be empty. */ - String query () const; + std::string const& + query () const; /** Returns the URL fragment, if any. */ - String fragment () const; + std::string const& + fragment () const; /** Returns the user information, if any. */ - String userinfo () const; - - /** Retrieve the full URL as a single string. */ - /** @{ */ - String toString () const; - std::string to_string() const; - /** @} */ + std::string const& + userinfo () const; private: - String m_scheme; - String m_host; - std::uint16_t m_port; - String m_port_string; - String m_path; - String m_query; - String m_fragment; - String m_userinfo; + std::string m_scheme; + std::string m_host; + std::uint16_t m_port = 0; + std::string m_port_string; + std::string m_path; + std::string m_query; + std::string m_fragment; + std::string m_userinfo; }; +/** Attempt to parse a string into a URL */ +std::pair +parse_URL(std::string const&); + +/** Retrieve the full URL as a single string. */ +std::string +to_string(URL const& url); + +/** Output stream conversion. */ +std::ostream& +operator<< (std::ostream& os, URL const& url); + /** URL comparisons. */ /** @{ */ -inline bool operator== (URL const& lhs, URL const& rhs) { return lhs.toString() == rhs.toString(); } -inline bool operator!= (URL const& lhs, URL const& rhs) { return ! (lhs.toString() == rhs.toString()); } -inline bool operator< (URL const& lhs, URL const& rhs) { return lhs.toString() < rhs.toString(); } -inline bool operator> (URL const& lhs, URL const& rhs) { return rhs.toString() < lhs.toString(); } -inline bool operator<= (URL const& lhs, URL const& rhs) { return ! (rhs.toString() < lhs.toString()); } -inline bool operator>= (URL const& lhs, URL const& rhs) { return ! (lhs.toString() < rhs.toString()); } -/** @} */ +inline bool +operator== (URL const& lhs, URL const& rhs) +{ + return to_string (lhs) == to_string (rhs); +} -/** Output stream conversion. */ -std::ostream& operator<< (std::ostream& os, URL const& url); +inline bool +operator!= (URL const& lhs, URL const& rhs) +{ + return to_string (lhs) != to_string (rhs); +} + +inline bool +operator< (URL const& lhs, URL const& rhs) +{ + return to_string (lhs) < to_string (rhs); +} + +inline bool operator> (URL const& lhs, URL const& rhs) +{ + return to_string (rhs) < to_string (lhs); +} + +inline bool +operator<= (URL const& lhs, URL const& rhs) +{ + return ! (to_string (rhs) < to_string (lhs)); +} + +inline bool +operator>= (URL const& lhs, URL const& rhs) +{ + return ! (to_string (lhs) < to_string (rhs)); +} +/** @} */ /** boost::hash support */ template @@ -128,7 +169,7 @@ void hash_append (Hasher& h, URL const& url) { using beast::hash_append; - hash_append (h, url.toString()); + hash_append (h, to_string (url)); } } @@ -140,8 +181,10 @@ namespace std { template <> struct hash { - std::size_t operator() (beast::URL const& v) const - { return v.toString().hash(); } + std::size_t operator() (beast::URL const& url) const + { + return std::hash{} (to_string (url)); + } }; } diff --git a/beast/http/impl/ParsedURL.cpp b/beast/http/impl/ParsedURL.cpp deleted file mode 100644 index 1bba014097..0000000000 --- a/beast/http/impl/ParsedURL.cpp +++ /dev/null @@ -1,150 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#include -#include - -#include - -#include - -namespace beast { - -ParsedURL::ParsedURL () - : m_error (0) -{ -} - -ParsedURL::ParsedURL (String const& url) -{ - std::string const ss (url.toStdString ()); - std::size_t const buflen (ss.size ()); - char const* const buf (ss.c_str ()); - - joyent::http_parser_url u; - - m_error = joyent::http_parser_parse_url (buf, buflen, false, &u); - - String scheme_; - String host_; - std::uint16_t port_ (0); - String port_string_; - String path_; - String query_; - String fragment_; - String userinfo_; - - if (m_error == 0) - { - if ((u.field_set & (1< : [ ? ] [ # ] - - e.g. - - foo://username:password@example.com:8042/over/there/index.dtb?type=animal&name=narwhal#nose -*/ -String URL::toString () const +std::pair +parse_URL(std::string const& url) { - String s; + std::size_t const buflen (url.size ()); + char const* const buf (url.c_str ()); - s = scheme () + "://"; - - if (userinfo () != String::empty) - s = userinfo () + "@"; + joyent::http_parser_url parser; - s = s + host (); + if (joyent::http_parser_parse_url (buf, buflen, false, &parser) != 0) + return std::make_pair (false, URL{}); - if (port () != 0) - s = s + ":" + String::fromNumber (port ()); + std::string scheme; + std::string host; + std::uint16_t port (0); + std::string port_string; + std::string path; + std::string query; + std::string fragment; + std::string userinfo; - s = s + path (); + if ((parser.field_set & (1< +#include #include -#include - namespace beast { -class ParsedURL_test : public unit_test::suite +class URL_test : public unit_test::suite { public: - void checkURL (String const& url) + void check_url_parsing (std::string const& url, bool expected) { - ParsedURL result (url); - expect (result.error () == 0); - expect (result.url ().toString () == url); + auto result = parse_URL (url); + + expect (result.first == expected, + (expected ? "Failed to parse " : "Succeeded in parsing ") + url); + expect (to_string (result.second) == url); } - void testURL () + void test_url_parsing () { - checkURL ("http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html"); + char const* const urls[] = + { + "http://en.wikipedia.org/wiki/URI#Examples_of_URI_references", + "ftp://ftp.funet.fi/pub/standards/RFC/rfc959.txt" + "ftp://test:test@example.com:21/path/specifier/is/here" + "http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html", + "foo://username:password@example.com:8042/over/there/index.dtb?type=animal&name=narwhal#nose", + }; + + testcase ("URL parsing"); + + for (auto url : urls) + check_url_parsing (url, true); } - void run () + void + run () { - testURL (); + test_url_parsing (); } }; -BEAST_DEFINE_TESTSUITE(ParsedURL,http,beast); +BEAST_DEFINE_TESTSUITE(URL,http,beast); } diff --git a/beast/module/asio/asio.h b/beast/module/asio/asio.h index 02d03a53a5..81d85f1041 100644 --- a/beast/module/asio/asio.h +++ b/beast/module/asio/asio.h @@ -27,7 +27,6 @@ #include #include -#include #include diff --git a/beast/module/asio/http/HTTPClientType.cpp b/beast/module/asio/http/HTTPClientType.cpp index 71d501ae2c..4db0862d09 100644 --- a/beast/module/asio/http/HTTPClientType.cpp +++ b/beast/module/asio/http/HTTPClientType.cpp @@ -148,14 +148,14 @@ public: if (url.port () != 0) { return Query ( - url.host().toStdString(), - url.port_string().toStdString(), + url.host(), + url.port_string(), Query::numeric_service); } return Query ( - url.host().toStdString(), - url.scheme().toStdString()); + url.host(), + url.scheme()); } //-------------------------------------------------------------------------- @@ -648,7 +648,7 @@ public: HTTPClientBase::New (Journal(), timeoutSeconds)); HTTPClientBase::result_type const& result ( - client->get (ParsedURL (s).url ())); + client->get (parse_URL (s.toStdString ()).second)); print (result.first, result.second); } @@ -659,7 +659,7 @@ public: std::unique_ptr client ( HTTPClientBase::New (Journal(), timeoutSeconds)); - client->async_get (t.get_io_service (), ParsedURL (s).url (), + client->async_get (t.get_io_service (), parse_URL (s.toStdString ()).second, std::bind (&HTTPClient_test::handle_get, this, std::placeholders::_1));