CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
url.cc
Go to the documentation of this file.
1 
5 #include "url.h"
6 
7 #include <algorithm>
8 
9 #include "util/string.h"
10 
11 const int Url::kDefaultPort = 80;
12 const char* Url::kDefaultProtocol = "http";
13 
14 Url* Url::Parse(const std::string& url, const std::string& default_protocol,
15  int default_port) {
16  if (url.empty()) {
17  return NULL;
18  }
19 
20  size_t cursor = 0;
21 
22  // Is there a protocol prefix?
23  std::string protocol = default_protocol;
24  size_t sep_pos = url.find("://");
25  if (sep_pos != std::string::npos) {
26  protocol = url.substr(0, sep_pos);
27  cursor = sep_pos + 3;
28  }
29 
30  std::string host;
31  std::string path;
32  uint64_t port = default_port;
33 
34  // Try to find another ":", preceding a port number
35  size_t col_pos = url.find(":", cursor);
36  if (col_pos != std::string::npos) {
37  // Port number was given
38  host = url.substr(cursor, col_pos - cursor);
39  cursor = col_pos + 1;
40 
41  size_t slash_pos = url.find("/", cursor);
42  if (slash_pos == 0) {
43  return NULL;
44  }
45 
46  // Check that part between ":" and "/" or the end of the string is an
47  // unsigned number
48  size_t port_end =
49  slash_pos == std::string::npos ? std::string::npos : slash_pos - cursor;
50  if (!String2Uint64Parse(url.substr(cursor, port_end), &port)) {
51  return NULL;
52  }
53 
54  if (slash_pos != std::string::npos) {
55  path = url.substr(slash_pos);
56  }
57  } else {
58  // No port number was given
59  size_t slash_pos = url.find("/", cursor);
60  if (slash_pos != std::string::npos) {
61  host = url.substr(cursor, slash_pos - cursor);
62  path = url.substr(slash_pos);
63  } else {
64  host = url.substr(cursor);
65  }
66  }
67 
68  // At the moment, host name validation is very basic
69  if (!ValidateHost(host)) {
70  return NULL;
71  }
72 
73  return new Url(protocol, host, path, port);
74 }
75 
76 bool Url::ValidateHost(const std::string& host) {
77  if (host.empty()) {
78  return false;
79  }
80 
81  // Host must not be just a number
82  uint64_t test;
83  if (String2Uint64Parse(host, &test)) {
84  return false;
85  }
86 
87  return true;
88 }
89 
90 Url::Url() : protocol_(), host_(), path_(), port_(), address_() {}
91 
92 Url::Url(const std::string& protocol, const std::string& host,
93  const std::string& path, int port)
94  : protocol_(protocol),
95  host_(host),
96  path_(path),
97  port_(port),
98  address_() {
99  if (port_ != kDefaultPort) {
100  address_ = protocol + "://" + host + ":" + StringifyInt(port_) + path;
101  } else {
102  address_ = protocol + "://" + host + path;
103  }
104 }
int port_
Definition: url.h:55
~Url()
Definition: url.cc:105
static const char * kDefaultProtocol
Definition: url.h:24
int port() const
Definition: url.h:45
static bool ValidateHost(const std::string &host)
Definition: url.cc:76
std::string protocol() const
Definition: url.h:41
bool String2Uint64Parse(const std::string &value, uint64_t *result)
Definition: string.cc:263
std::string path() const
Definition: url.h:44
std::string address_
Definition: url.h:56
Url()
Definition: url.cc:90
string StringifyInt(const int64_t value)
Definition: string.cc:78
std::string host() const
Definition: url.h:43
static Url * Parse(const std::string &url, const std::string &default_protocol=kDefaultProtocol, int default_port=kDefaultPort)
Definition: url.cc:14
Definition: url.h:10
static const int kDefaultPort
Definition: url.h:23