BitShares-Core  4.0.0
BitShares blockchain implementation and command-line interface software
url.cpp
Go to the documentation of this file.
1 #include <fc/network/url.hpp>
2 #include <fc/io/sstream.hpp>
4 #include <fc/log/logger.hpp>
5 #include <sstream>
6 
7 namespace fc
8 {
9  namespace detail
10  {
11  class url_impl
12  {
13  public:
14  void parse( const std::string& s )
15  {
16  std::stringstream ss(s);
17  std::string skip,_lpath,_largs,luser,lpass;
18  std::getline( ss, _proto, ':' );
19  std::getline( ss, skip, '/' );
20  std::getline( ss, skip, '/' );
21 
22  if( s.find('@') != size_t(std::string::npos) ) {
23  std::string user_pass;
24  std::getline( ss, user_pass, '@' );
25  std::stringstream upss(user_pass);
26  if( user_pass.find( ':' ) != size_t(std::string::npos) ) {
27  std::getline( upss, luser, ':' );
28  std::getline( upss, lpass, ':' );
29  _user = std::move(luser);
30  _pass = std::move(lpass);
31  } else {
32  _user = std::move(user_pass);
33  }
34  }
35  std::string host_port;
36  std::getline( ss, host_port, '/' );
37  auto pos = host_port.find( ':' );
38  if( pos != std::string::npos ) {
39  try {
40  _port = static_cast<uint16_t>(to_uint64( host_port.substr( pos+1 ) ));
41  } catch ( ... ) {
42  FC_THROW_EXCEPTION( parse_error_exception, "Unable to parse port field in url",( "url", s ) );
43  }
44  _host = host_port.substr(0,pos);
45  } else {
46  _host = std::move(host_port);
47  }
48  std::getline( ss, _lpath, '?' );
49 #ifdef WIN32
50  // On windows, a URL like file:///c:/autoexec.bat would result in _lpath = c:/autoexec.bat
51  // which is what we really want (it's already an absolute path)
52  if (!stricmp(_proto.c_str(), "file"))
53  _path = _lpath;
54  else
55  _path = fc::path( "/" ) / _lpath; // let other schemes behave like unix
56 #else
57  // On unix, a URL like file:///etc/rc.local would result in _lpath = etc/rc.local
58  // but we really want to make it the absolute path /etc/rc.local
59  _path = fc::path( "/" ) / _lpath;
60 #endif
61  std::getline( ss, _largs );
62  if( _args.valid() && _args->size() )
63  {
64  // TODO: args = std::move(_args);
65  }
66  }
67 
68  string _proto;
75  };
76  }
77 
78  void to_variant( const url& u, fc::variant& v, uint32_t max_depth )
79  {
80  v = std::string(u);
81  }
82  void from_variant( const fc::variant& v, url& u, uint32_t max_depth )
83  {
84  u = url( v.as_string() );
85  }
86 
87  url::operator string()const
88  {
89  std::stringstream ss;
90  ss<<my->_proto<<"://";
91  if( my->_user.valid() ) {
92  ss << *my->_user;
93  if( my->_pass.valid() ) {
94  ss<<":"<<*my->_pass;
95  }
96  ss<<"@";
97  }
98  if( my->_host.valid() ) ss<<*my->_host;
99  if( my->_port.valid() ) ss<<":"<<*my->_port;
100  if( my->_path.valid() ) ss<<my->_path->generic_string();
101  return ss.str();
102  }
103 
104  url::url( const std::string& u )
105  :my( std::make_shared<detail::url_impl>() )
106  {
107  my->parse(u);
108  }
109 
110  std::shared_ptr<detail::url_impl> get_null_url()
111  {
112  static auto u = std::make_shared<detail::url_impl>();
113  return u;
114  }
115 
117  :my( get_null_url() )
118  { }
119 
120  url::url( const url& u )
121  :my(u.my){}
122 
123  url::url( url&& u )
124  :my( std::move(u.my) )
125  {
126  u.my = get_null_url();
127  }
128 
129  url::url( const mutable_url& mu )
130  :my( std::make_shared<detail::url_impl>(*mu.my) )
131  {
132 
133  }
135  :my( std::move( mu.my ) )
136  { }
137 
139 
140  url& url::operator=(const url& u )
141  {
142  my = u.my;
143  return *this;
144  }
145 
147  {
148  if( this != &u )
149  {
150  my = std::move(u.my);
151  u.my= get_null_url();
152  }
153  return *this;
154  }
156  {
157  my = std::make_shared<detail::url_impl>(*u.my);
158  return *this;
159  }
161  {
162  my = std::move(u.my);
163  return *this;
164  }
165 
166  string url::proto()const
167  {
168  return my->_proto;
169  }
171  {
172  return my->_host;
173  }
175  {
176  return my->_user;
177  }
179  {
180  return my->_pass;
181  }
183  {
184  return my->_path;
185  }
187  {
188  return my->_args;
189  }
191  {
192  return my->_port;
193  }
194 
195 
196 
197 }
198 
opath path() const
Definition: url.cpp:182
bool valid() const
Definition: optional.hpp:186
fc::istream & getline(fc::istream &, std::string &, char delim= '\n')
Definition: iostream.cpp:78
ostring user() const
Definition: url.cpp:174
string proto() const
Definition: url.cpp:166
url & operator=(const url &c)
Definition: url.cpp:140
~url()
Definition: url.cpp:138
void to_variant(const flat_set< T, A... > &var, variant &vo, uint32_t _max_depth)
Definition: flat.hpp:105
ostring pass() const
Definition: url.cpp:178
ostring host() const
Definition: url.cpp:170
ovariant_object args() const
Definition: url.cpp:186
fc::optional< uint16_t > port() const
Definition: url.cpp:190
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object&#39;s.
Definition: variant.hpp:198
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:378
ostring _pass
Definition: url.cpp:71
uint64_t to_uint64(const std::string &)
Definition: string.cpp:47
Defines exception&#39;s used by fc.
std::shared_ptr< detail::url_impl > get_null_url()
Definition: url.cpp:110
void from_variant(const variant &var, flat_set< T, A... > &vo, uint32_t _max_depth)
Definition: flat.hpp:116
Definition: api.hpp:15
url()
Definition: url.cpp:116
Definition: url.hpp:22
fc::optional< uint16_t > _port
Definition: url.cpp:74
ovariant_object _args
Definition: url.cpp:73
wraps boost::filesystem::path to provide platform independent path manipulation.
Definition: filesystem.hpp:28
void parse(const std::string &s)
Definition: url.cpp:14
std::string as_string() const
Definition: variant.cpp:469
ostring _user
Definition: url.cpp:70
ostring _host
Definition: url.cpp:69
size_t size() const