Fix URL compositing in Beast (RIPD-636).

This commit is contained in:
Nik Bougalis
2014-10-13 18:42:22 -07:00
committed by Tom Ritchford
parent 5b4a501f68
commit 35935adc98
15 changed files with 309 additions and 418 deletions

View File

@@ -392,9 +392,6 @@
<ClCompile Include="..\..\src\beast\beast\http\impl\method.cpp"> <ClCompile Include="..\..\src\beast\beast\http\impl\method.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild> <ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\impl\ParsedURL.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\impl\raw_parser.cpp"> <ClCompile Include="..\..\src\beast\beast\http\impl\raw_parser.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild> <ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile> </ClCompile>
@@ -405,8 +402,6 @@
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\beast\beast\http\method.h"> <ClInclude Include="..\..\src\beast\beast\http\method.h">
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\beast\beast\http\ParsedURL.h">
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\http\parser.h"> <ClInclude Include="..\..\src\beast\beast\http\parser.h">
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\beast\beast\http\raw_parser.h"> <ClInclude Include="..\..\src\beast\beast\http\raw_parser.h">
@@ -419,15 +414,15 @@
<ClCompile Include="..\..\src\beast\beast\http\tests\client_session.test.cpp"> <ClCompile Include="..\..\src\beast\beast\http\tests\client_session.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild> <ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\tests\ParsedURL.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\tests\parser.test.cpp"> <ClCompile Include="..\..\src\beast\beast\http\tests\parser.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild> <ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\tests\rfc2616.test.cpp"> <ClCompile Include="..\..\src\beast\beast\http\tests\rfc2616.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild> <ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\tests\URL.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\tests\urls_large_data.cpp"> <ClCompile Include="..\..\src\beast\beast\http\tests\urls_large_data.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild> <ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile> </ClCompile>
@@ -3185,11 +3180,6 @@
<ClCompile Include="..\..\src\ripple\rpc\impl\Manager.cpp"> <ClCompile Include="..\..\src\ripple\rpc\impl\Manager.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild> <ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\NewHandler.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\impl\NewHandlerBase.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\impl\ParseAccountIds.cpp"> <ClCompile Include="..\..\src\ripple\rpc\impl\ParseAccountIds.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild> <ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile> </ClCompile>
@@ -3201,6 +3191,12 @@
<ClCompile Include="..\..\src\ripple\rpc\impl\RPCServerHandler.cpp"> <ClCompile Include="..\..\src\ripple\rpc\impl\RPCServerHandler.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild> <ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\Status.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\Status_test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\TransactionSign.cpp"> <ClCompile Include="..\..\src\ripple\rpc\impl\TransactionSign.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild> <ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile> </ClCompile>
@@ -3212,8 +3208,6 @@
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple\rpc\Manager.h"> <ClInclude Include="..\..\src\ripple\rpc\Manager.h">
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple\rpc\NewHandler.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\rpc\Request.h"> <ClInclude Include="..\..\src\ripple\rpc\Request.h">
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple\rpc\RPCHandler.h"> <ClInclude Include="..\..\src\ripple\rpc\RPCHandler.h">

View File

@@ -960,9 +960,6 @@
<ClCompile Include="..\..\src\beast\beast\http\impl\method.cpp"> <ClCompile Include="..\..\src\beast\beast\http\impl\method.cpp">
<Filter>beast\http\impl</Filter> <Filter>beast\http\impl</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\impl\ParsedURL.cpp">
<Filter>beast\http\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\impl\raw_parser.cpp"> <ClCompile Include="..\..\src\beast\beast\http\impl\raw_parser.cpp">
<Filter>beast\http\impl</Filter> <Filter>beast\http\impl</Filter>
</ClCompile> </ClCompile>
@@ -975,9 +972,6 @@
<ClInclude Include="..\..\src\beast\beast\http\method.h"> <ClInclude Include="..\..\src\beast\beast\http\method.h">
<Filter>beast\http</Filter> <Filter>beast\http</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\beast\beast\http\ParsedURL.h">
<Filter>beast\http</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\http\parser.h"> <ClInclude Include="..\..\src\beast\beast\http\parser.h">
<Filter>beast\http</Filter> <Filter>beast\http</Filter>
</ClInclude> </ClInclude>
@@ -993,15 +987,15 @@
<ClCompile Include="..\..\src\beast\beast\http\tests\client_session.test.cpp"> <ClCompile Include="..\..\src\beast\beast\http\tests\client_session.test.cpp">
<Filter>beast\http\tests</Filter> <Filter>beast\http\tests</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\tests\ParsedURL.cpp">
<Filter>beast\http\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\tests\parser.test.cpp"> <ClCompile Include="..\..\src\beast\beast\http\tests\parser.test.cpp">
<Filter>beast\http\tests</Filter> <Filter>beast\http\tests</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\tests\rfc2616.test.cpp"> <ClCompile Include="..\..\src\beast\beast\http\tests\rfc2616.test.cpp">
<Filter>beast\http\tests</Filter> <Filter>beast\http\tests</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\tests\URL.test.cpp">
<Filter>beast\http\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\beast\beast\http\tests\urls_large_data.cpp"> <ClCompile Include="..\..\src\beast\beast\http\tests\urls_large_data.cpp">
<Filter>beast\http\tests</Filter> <Filter>beast\http\tests</Filter>
</ClCompile> </ClCompile>
@@ -4371,12 +4365,6 @@
<ClCompile Include="..\..\src\ripple\rpc\impl\Manager.cpp"> <ClCompile Include="..\..\src\ripple\rpc\impl\Manager.cpp">
<Filter>ripple\rpc\impl</Filter> <Filter>ripple\rpc\impl</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\NewHandler.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\impl\NewHandlerBase.h">
<Filter>ripple\rpc\impl</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\impl\ParseAccountIds.cpp"> <ClCompile Include="..\..\src\ripple\rpc\impl\ParseAccountIds.cpp">
<Filter>ripple\rpc\impl</Filter> <Filter>ripple\rpc\impl</Filter>
</ClCompile> </ClCompile>
@@ -4389,6 +4377,12 @@
<ClCompile Include="..\..\src\ripple\rpc\impl\RPCServerHandler.cpp"> <ClCompile Include="..\..\src\ripple\rpc\impl\RPCServerHandler.cpp">
<Filter>ripple\rpc\impl</Filter> <Filter>ripple\rpc\impl</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\Status.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\Status_test.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\TransactionSign.cpp"> <ClCompile Include="..\..\src\ripple\rpc\impl\TransactionSign.cpp">
<Filter>ripple\rpc\impl</Filter> <Filter>ripple\rpc\impl</Filter>
</ClCompile> </ClCompile>
@@ -4404,9 +4398,6 @@
<ClInclude Include="..\..\src\ripple\rpc\Manager.h"> <ClInclude Include="..\..\src\ripple\rpc\Manager.h">
<Filter>ripple\rpc</Filter> <Filter>ripple\rpc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple\rpc\NewHandler.h">
<Filter>ripple\rpc</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\rpc\Request.h"> <ClInclude Include="..\..\src\ripple\rpc\Request.h">
<Filter>ripple\rpc</Filter> <Filter>ripple\rpc</Filter>
</ClInclude> </ClInclude>

View File

@@ -25,14 +25,13 @@
#include <beast/http/impl/basic_url.cpp> #include <beast/http/impl/basic_url.cpp>
#include <beast/http/impl/joyent_parser.cpp> #include <beast/http/impl/joyent_parser.cpp>
#include <beast/http/impl/method.cpp> #include <beast/http/impl/method.cpp>
#include <beast/http/impl/ParsedURL.cpp>
#include <beast/http/impl/raw_parser.cpp> #include <beast/http/impl/raw_parser.cpp>
#include <beast/http/impl/URL.cpp> #include <beast/http/impl/URL.cpp>
#include <beast/http/tests/basic_url.test.cpp> #include <beast/http/tests/basic_url.test.cpp>
#include <beast/http/tests/client_session.test.cpp> #include <beast/http/tests/client_session.test.cpp>
#include <beast/http/tests/parser.test.cpp> #include <beast/http/tests/parser.test.cpp>
#include <beast/http/tests/ParsedURL.cpp>
#include <beast/http/tests/rfc2616.test.cpp> #include <beast/http/tests/rfc2616.test.cpp>
#include <beast/http/tests/URL.test.cpp>
#include <beast/http/tests/urls_large_data.cpp> #include <beast/http/tests/urls_large_data.cpp>

View File

@@ -1,51 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 <beast/Strings.h>
#include <beast/http/URL.h>
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

View File

@@ -20,8 +20,6 @@
#ifndef BEAST_HTTP_URL_H_INCLUDED #ifndef BEAST_HTTP_URL_H_INCLUDED
#define BEAST_HTTP_URL_H_INCLUDED #define BEAST_HTTP_URL_H_INCLUDED
#include <beast/strings/String.h>
#include <ios> #include <ios>
namespace beast { namespace beast {
@@ -32,94 +30,137 @@ namespace beast {
class URL class URL
{ {
public: public:
/** Construct an empty URL. */
explicit URL ();
/** Construct a URL from it's components. */ /** Construct a URL from it's components. */
URL ( URL (
String schema_, std::string schema_,
String host_, std::string host_,
std::uint16_t port_, std::uint16_t port_,
String port_string_, std::string port_string_,
String path_, std::string path_,
String query_ = "", std::string query_ = "",
String fragment_ = "", std::string fragment_ = "",
String userinfo_ = ""); std::string userinfo_ = "");
/** Construct an empty URL. */
explicit URL () = default;
/** Copy construct a URL. */ /** Copy construct a URL. */
URL (URL const& other); URL (URL const& other) = default;
/** Copy assign a URL. */ /** 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. */ /** Returns `true` if this is an empty URL. */
bool empty () const; bool
empty () const;
/** Returns the scheme of the URL. /** Returns the scheme of the URL.
If no scheme was specified, the string will be empty. If no scheme was specified, the string will be empty.
*/ */
String scheme () const; std::string const&
scheme () const;
/** Returns the host of the URL. /** Returns the host of the URL.
If no host was specified, the string will be empty. 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. /** Returns the port number as an integer.
If no port was specified, the value will be zero. 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. /** Returns the port number as a string.
If no port was specified, the string will be empty. 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. /** Returns the path of the URL.
If no path was specified, the string will be empty. 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. /** Returns the query parameters portion of the URL.
If no query parameters were present, the string will be empty. 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. */ /** Returns the URL fragment, if any. */
String fragment () const; std::string const&
fragment () const;
/** Returns the user information, if any. */ /** Returns the user information, if any. */
String userinfo () const; std::string const&
userinfo () const;
/** Retrieve the full URL as a single string. */
/** @{ */
String toString () const;
std::string to_string() const;
/** @} */
private: private:
String m_scheme; std::string m_scheme;
String m_host; std::string m_host;
std::uint16_t m_port; std::uint16_t m_port = 0;
String m_port_string; std::string m_port_string;
String m_path; std::string m_path;
String m_query; std::string m_query;
String m_fragment; std::string m_fragment;
String m_userinfo; std::string m_userinfo;
}; };
/** Attempt to parse a string into a URL */
std::pair<bool, URL>
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. */ /** URL comparisons. */
/** @{ */ /** @{ */
inline bool operator== (URL const& lhs, URL const& rhs) { return lhs.toString() == rhs.toString(); } inline bool
inline bool operator!= (URL const& lhs, URL const& rhs) { return ! (lhs.toString() == rhs.toString()); } operator== (URL const& lhs, URL const& rhs)
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(); } return to_string (lhs) == to_string (rhs);
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()); }
/** @} */
/** Output stream conversion. */ inline bool
std::ostream& operator<< (std::ostream& os, URL const& url); 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 */ /** boost::hash support */
template <class Hasher> template <class Hasher>
@@ -128,7 +169,7 @@ void
hash_append (Hasher& h, URL const& url) hash_append (Hasher& h, URL const& url)
{ {
using beast::hash_append; using beast::hash_append;
hash_append (h, url.toString()); hash_append (h, to_string (url));
} }
} }
@@ -140,8 +181,10 @@ namespace std {
template <> template <>
struct hash <beast::URL> struct hash <beast::URL>
{ {
std::size_t operator() (beast::URL const& v) const std::size_t operator() (beast::URL const& url) const
{ return v.toString().hash(); } {
return std::hash<std::string>{} (to_string (url));
}
}; };
} }

View File

@@ -1,150 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 <beast/http/ParsedURL.h>
#include <beast/strings/String.h>
#include <beast/http/impl/joyent_parser.h>
#include <cstdint>
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<<joyent::UF_SCHEMA)) != 0)
{
scheme_ = String (
buf + u.field_data [joyent::UF_SCHEMA].off,
u.field_data [joyent::UF_SCHEMA].len);
}
if ((u.field_set & (1<<joyent::UF_HOST)) != 0)
{
host_ = String (
buf + u.field_data [joyent::UF_HOST].off,
u.field_data [joyent::UF_HOST].len);
}
if ((u.field_set & (1<<joyent::UF_PORT)) != 0)
{
port_ = u.port;
port_string_ = String (
buf + u.field_data [joyent::UF_PORT].off,
u.field_data [joyent::UF_PORT].len);
}
else
{
port_ = 0;
}
if ((u.field_set & (1<<joyent::UF_PATH)) != 0)
{
path_ = String (
buf + u.field_data [joyent::UF_PATH].off,
u.field_data [joyent::UF_PATH].len);
}
if ((u.field_set & (1<<joyent::UF_QUERY)) != 0)
{
query_ = String (
buf + u.field_data [joyent::UF_QUERY].off,
u.field_data [joyent::UF_QUERY].len);
}
if ((u.field_set & (1<<joyent::UF_FRAGMENT)) != 0)
{
fragment_ = String (
buf + u.field_data [joyent::UF_FRAGMENT].off,
u.field_data [joyent::UF_FRAGMENT].len);
}
if ((u.field_set & (1<<joyent::UF_USERINFO)) != 0)
{
userinfo_ = String (
buf + u.field_data [joyent::UF_USERINFO].off,
u.field_data [joyent::UF_USERINFO].len);
}
m_url = URL (
scheme_,
host_,
port_,
port_string_,
path_,
query_,
fragment_,
userinfo_);
}
}
ParsedURL::ParsedURL (int error, URL const& url)
: m_error (error)
, m_url (url)
{
}
ParsedURL::ParsedURL (ParsedURL const& other)
: m_error (other.m_error)
, m_url (other.m_url)
{
}
ParsedURL& ParsedURL::operator= (ParsedURL const& other)
{
m_error = other.m_error;
m_url = other.m_url;
return *this;
}
int ParsedURL::error () const
{
return m_error;
}
URL ParsedURL::url () const
{
return m_url;
}
}

View File

@@ -21,146 +21,209 @@
namespace beast { namespace beast {
URL::URL ()
: m_port (0)
{
}
URL::URL ( URL::URL (
String scheme_, std::string scheme_,
String host_, std::string host_,
std::uint16_t port_, std::uint16_t port_,
String port_string_, std::string port_string_,
String path_, std::string path_,
String query_, std::string query_,
String fragment_, std::string fragment_,
String userinfo_) std::string userinfo_)
: m_scheme (scheme_) : m_scheme (scheme_)
, m_host (host_) , m_host (host_)
, m_port (port_) , m_port (port_)
, m_port_string (port_string_) , m_port_string (port_string_)
, m_path (path_) , m_path (path_)
, m_query (query_) , m_query (query_)
, m_fragment (fragment_) , m_fragment (fragment_)
, m_userinfo (userinfo_) , m_userinfo (userinfo_)
{ {
} }
URL::URL (URL const& other)
: m_scheme (other.m_scheme)
, m_host (other.m_host)
, m_port (other.m_port)
, m_port_string (other.m_port_string)
, m_path (other.m_path)
, m_query (other.m_query)
, m_fragment (other.m_fragment)
, m_userinfo (other.m_userinfo)
{
}
URL& URL::operator= (URL const& other)
{
m_scheme = other.m_scheme;
m_host = other.m_host;
m_port = other.m_port;
m_port_string = other.m_port_string;
m_path = other.m_path;
m_query = other.m_query;
m_fragment = other.m_fragment;
m_userinfo = other.m_userinfo;
return *this;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool URL::empty () const bool
URL::empty () const
{ {
return m_scheme == String::empty; return m_scheme.empty ();
} }
String URL::scheme () const std::string
const& URL::scheme () const
{ {
return m_scheme; return m_scheme;
} }
String URL::host () const std::string
const& URL::host () const
{ {
return m_host; return m_host;
} }
String URL::port_string () const std::string
const& URL::port_string () const
{ {
return m_port_string; return m_port_string;
} }
std::uint16_t URL::port () const std::uint16_t
URL::port () const
{ {
return m_port; return m_port;
} }
String URL::path () const std::string
const& URL::path () const
{ {
return m_path; return m_path;
} }
String URL::query () const std::string
const& URL::query () const
{ {
return m_query; return m_query;
} }
String URL::fragment () const std::string
const& URL::fragment () const
{ {
return m_fragment; return m_fragment;
} }
String URL::userinfo () const std::string
const& URL::userinfo () const
{ {
return m_userinfo; return m_userinfo;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/* std::pair<bool, URL>
From parse_URL(std::string const& url)
http://en.wikipedia.org/wiki/URI_scheme
<scheme name> : <hierarchical part> [ ? <query> ] [ # <fragment> ]
e.g.
foo://username:password@example.com:8042/over/there/index.dtb?type=animal&name=narwhal#nose
*/
String URL::toString () const
{ {
String s; std::size_t const buflen (url.size ());
char const* const buf (url.c_str ());
s = scheme () + "://"; joyent::http_parser_url parser;
if (userinfo () != String::empty)
s = userinfo () + "@";
s = s + host (); if (joyent::http_parser_parse_url (buf, buflen, false, &parser) != 0)
return std::make_pair (false, URL{});
if (port () != 0) std::string scheme;
s = s + ":" + String::fromNumber (port ()); 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<<joyent::UF_SCHEMA)) != 0)
{
scheme = std::string (
buf + parser.field_data [joyent::UF_SCHEMA].off,
parser.field_data [joyent::UF_SCHEMA].len);
}
if (query () != String::empty) if ((parser.field_set & (1<<joyent::UF_HOST)) != 0)
s = "?" + query (); {
host = std::string (
buf + parser.field_data [joyent::UF_HOST].off,
parser.field_data [joyent::UF_HOST].len);
}
if (fragment () != String::empty) if ((parser.field_set & (1<<joyent::UF_PORT)) != 0)
s = "#" + fragment (); {
port = parser.port;
port_string = std::string (
buf + parser.field_data [joyent::UF_PORT].off,
parser.field_data [joyent::UF_PORT].len);
}
if ((parser.field_set & (1<<joyent::UF_PATH)) != 0)
{
path = std::string (
buf + parser.field_data [joyent::UF_PATH].off,
parser.field_data [joyent::UF_PATH].len);
}
if ((parser.field_set & (1<<joyent::UF_QUERY)) != 0)
{
query = std::string (
buf + parser.field_data [joyent::UF_QUERY].off,
parser.field_data [joyent::UF_QUERY].len);
}
if ((parser.field_set & (1<<joyent::UF_FRAGMENT)) != 0)
{
fragment = std::string (
buf + parser.field_data [joyent::UF_FRAGMENT].off,
parser.field_data [joyent::UF_FRAGMENT].len);
}
if ((parser.field_set & (1<<joyent::UF_USERINFO)) != 0)
{
userinfo = std::string (
buf + parser.field_data [joyent::UF_USERINFO].off,
parser.field_data [joyent::UF_USERINFO].len);
}
return std::make_pair (true,
URL {scheme, host, port, port_string, path, query, fragment, userinfo});
}
std::string
to_string (URL const& url)
{
std::string s;
if (!url.empty ())
{
// Pre-allocate enough for components and inter-component separators
s.reserve (
url.scheme ().length () + url.userinfo ().length () +
url.host ().length () + url.port_string ().length () +
url.query ().length () + url.fragment ().length () + 16);
s.append (url.scheme ());
s.append ("://");
if (!url.userinfo ().empty ())
{
s.append (url.userinfo ());
s.append ("@");
}
s.append (url.host ());
if (url.port ())
{
s.append (":");
s.append (url.port_string ());
}
s.append (url.path ());
if (!url.query ().empty ())
{
s.append ("?");
s.append (url.query ());
}
if (!url.fragment ().empty ())
{
s.append ("#");
s.append (url.fragment ());
}
}
return s; return s;
} }
std::string URL::to_string() const std::ostream&
operator<< (std::ostream &os, URL const& url)
{ {
return toString().toStdString(); os << to_string (url);
}
std::ostream& operator<< (std::ostream &os, URL const& url)
{
os << url.to_string();
return os; return os;
} }

View File

@@ -17,35 +17,48 @@
*/ */
//============================================================================== //==============================================================================
#include <beast/http/ParsedURL.h> #include <beast/http/URL.h>
#include <beast/unit_test/suite.h> #include <beast/unit_test/suite.h>
#include <beast/http/impl/joyent_parser.h>
namespace beast { namespace beast {
class ParsedURL_test : public unit_test::suite class URL_test : public unit_test::suite
{ {
public: public:
void checkURL (String const& url) void check_url_parsing (std::string const& url, bool expected)
{ {
ParsedURL result (url); auto result = parse_URL (url);
expect (result.error () == 0);
expect (result.url ().toString () == 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);
} }

View File

@@ -27,7 +27,6 @@
#include <beast/module/asio/system/BoostIncludes.h> #include <beast/module/asio/system/BoostIncludes.h>
#include <beast/http/URL.h> #include <beast/http/URL.h>
#include <beast/http/ParsedURL.h>
#include <beast/asio/IPAddressConversion.h> #include <beast/asio/IPAddressConversion.h>

View File

@@ -148,14 +148,14 @@ public:
if (url.port () != 0) if (url.port () != 0)
{ {
return Query ( return Query (
url.host().toStdString(), url.host(),
url.port_string().toStdString(), url.port_string(),
Query::numeric_service); Query::numeric_service);
} }
return Query ( return Query (
url.host().toStdString(), url.host(),
url.scheme().toStdString()); url.scheme());
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@@ -648,7 +648,7 @@ public:
HTTPClientBase::New (Journal(), timeoutSeconds)); HTTPClientBase::New (Journal(), timeoutSeconds));
HTTPClientBase::result_type const& result ( HTTPClientBase::result_type const& result (
client->get (ParsedURL (s).url ())); client->get (parse_URL (s.toStdString ()).second));
print (result.first, result.second); print (result.first, result.second);
} }
@@ -659,7 +659,7 @@ public:
std::unique_ptr <HTTPClientBase> client ( std::unique_ptr <HTTPClientBase> client (
HTTPClientBase::New (Journal(), timeoutSeconds)); 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::bind (&HTTPClient_test::handle_get, this,
std::placeholders::_1)); std::placeholders::_1));

View File

@@ -194,8 +194,7 @@ bool parseIpPort (std::string const& strSource, std::string& strIP, int& iPort)
return bValid; return bValid;
} }
// VFALCO TODO Callers should be using beast::URL and beast::ParsedURL, not this home-brew. // TODO Callers should be using beast::URL and beast::parse_URL instead.
//
bool parseUrl (std::string const& strUrl, std::string& strScheme, std::string& strDomain, int& iPort, std::string& strPath) bool parseUrl (std::string const& strUrl, std::string& strScheme, std::string& strDomain, int& iPort, std::string& strPath)
{ {
// scheme://username:password@hostname:port/rest // scheme://username:password@hostname:port/rest

View File

@@ -22,7 +22,7 @@
#include <ripple/basics/Log.h> #include <ripple/basics/Log.h>
#include <ripple/core/SystemParameters.h> #include <ripple/core/SystemParameters.h>
#include <ripple/net/HTTPClient.h> #include <ripple/net/HTTPClient.h>
#include <beast/http/ParsedURL.h> #include <beast/http/URL.h>
#include <beast/module/core/text/LexicalCast.h> #include <beast/module/core/text/LexicalCast.h>
#include <beast/streams/debug_ostream.h> #include <beast/streams/debug_ostream.h>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
@@ -843,9 +843,7 @@ beast::File Config::getValidatorsFile () const
beast::URL Config::getValidatorsURL () const beast::URL Config::getValidatorsURL () const
{ {
//String s = "https://" + VALIDATORS_SITE + VALIDATORS_URI; return beast::parse_URL (VALIDATORS_SITE).second;
beast::String s = VALIDATORS_SITE;
return beast::ParsedURL (s).url ();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@@ -104,7 +104,7 @@ public:
for (SiteFiles::const_iterator iter (state->files.begin()); for (SiteFiles::const_iterator iter (state->files.begin());
iter != state->files.end(); ++iter) iter != state->files.end(); ++iter)
{ {
listener.onSiteFileFetch (iter->first.to_string(), iter->second); listener.onSiteFileFetch (to_string (iter->first), iter->second);
} }
state->listeners.insert (&listener); state->listeners.insert (&listener);
@@ -118,34 +118,30 @@ public:
void addURL (std::string const& urlstr) void addURL (std::string const& urlstr)
{ {
beast::ParsedURL const p (urlstr); auto url = beast::parse_URL (urlstr);
if (p.error()) if (!url.first)
{ {
m_journal.error << m_journal.error <<
"Error parsing '" << urlstr << "'"; "Error parsing '" << urlstr << "'";
return; return;
} }
beast::URL const& url (p.url()); auto const result (m_client->get (url.second));
auto const result (m_client->get (url));
//---
boost::system::error_code const error (result.first); boost::system::error_code const error (result.first);
if (error) if (error)
{ {
m_journal.error m_journal.error <<
<< "HTTP GET '" << url << "HTTP GET '" << url.second <<
"' failed: " << error.message(); "' failed: " << error.message();
return; return;
} }
beast::HTTPResponse const& response (*result.second); beast::HTTPResponse const& response (*result.second);
processResponse (url, response); processResponse (url.second, response);
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@@ -175,7 +171,7 @@ public:
iter != state->listeners.end(); ++iter) iter != state->listeners.end(); ++iter)
{ {
Listener* const listener (*iter); Listener* const listener (*iter);
listener->onSiteFileFetch (url.to_string(), siteFile); listener->onSiteFileFetch (to_string (url), siteFile);
} }
} }

View File

@@ -39,10 +39,7 @@ public:
std::string to_string () const std::string to_string () const
{ {
std::stringstream ss; return "File: '" + m_file.getFullPathName().toStdString() + "'";
ss <<
"File: '" << m_file.getFullPathName().toStdString() + "'";
return ss.str();
} }
std::string uniqueID () const std::string uniqueID () const

View File

@@ -40,20 +40,20 @@ public:
std::string to_string () const std::string to_string () const
{ {
std::stringstream ss; using std::to_string;
ss << return "URL: '" + to_string (m_url) + "'";
"URL: '" << m_url.to_string() << "'";
return ss.str();
} }
std::string uniqueID () const std::string uniqueID () const
{ {
return "URL," + m_url.to_string(); using std::to_string;
return "URL," + to_string (m_url);
} }
std::string createParam () std::string createParam ()
{ {
return m_url.to_string(); using std::to_string;
return to_string (m_url);
} }
void cancel () void cancel ()