2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "common/url.h"
22 #include "common/logger.h"
23 #include "common/string_utils.h"
29 const char* kSchemeTypeFile = "file";
30 const char* kSchemeTypeHttp = "http";
31 const char* kSchemeTypeHttps = "https";
32 const char* kSchemeTypeSsh = "ssh";
33 const char* kSchemeTypeFtp = "ftp";
35 // length of scheme identifier ://
36 const int kSchemeIdLen = 3;
43 int GetDefaultPort(const std::string& scheme) {
44 if (scheme == kSchemeTypeHttp) return kPortHttp;
45 else if (scheme == kSchemeTypeHttps) return kPortHttps;
46 else if (scheme == kSchemeTypeSsh) return kPortSsh;
47 else if (scheme == kSchemeTypeFtp) return kPortFtp;
56 explicit URLImpl(const std::string& url);
59 std::string url() const { return url_; }
60 std::string scheme() const { return scheme_; }
61 std::string domain() const { return domain_; }
62 int port() const { return port_; }
63 std::string path() const { return path_; }
74 void ExtractDomainPort();
78 URLImpl::URLImpl(const std::string& url) : port_(0) {
83 if (!ExtractScheme()) {
89 if (scheme_ != kSchemeTypeFile)
95 bool URLImpl::ExtractScheme() {
96 size_t end_of_scheme = 0;
97 if (url_.find("://") != std::string::npos) {
98 end_of_scheme = url_.find("://");
99 std::string scheme = url_.substr(0, end_of_scheme);
100 std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower);
108 void URLImpl::ExtractDomain() {
109 size_t start_of_domain = scheme_.empty() ?
110 0 : scheme_.length() + kSchemeIdLen;
111 size_t end_of_domain = url_.find_first_of('/', start_of_domain);
112 size_t at = url_.find_first_of('@', start_of_domain);
113 if (at < end_of_domain) {
114 start_of_domain = at + 1;
117 url_.substr(start_of_domain, end_of_domain == std::string::npos ?
118 std::string::npos : end_of_domain - start_of_domain);
119 LOGGER(INFO) << "Extract Domain is " << domain_;
122 void URLImpl::ExtractDomainPort() {
124 std::string domain = domain_;
126 // Decide start position to find port considering IPv6 case
127 size_t start_pos = domain.find('@');
128 start_pos = (start_pos != std::string::npos) ? start_pos + 1 : 0;
129 if (domain[start_pos] == '[')
130 start_pos = domain.find(']', start_pos+1);
132 size_t port_separator =
133 domain.find_first_of(':', start_pos != std::string::npos ? start_pos : 0);
134 if (port_separator != std::string::npos) {
135 domain_ = domain.substr(0, port_separator);
136 std::string port = domain.substr(port_separator+1);
138 port_ = GetDefaultPort(scheme_);
141 port_ = std::stoi(port);
143 port_ = GetDefaultPort(scheme_);
148 port_ = GetDefaultPort(scheme_);
152 void URLImpl::ExtractPath() {
153 std::string sub_url = url_.substr(scheme_.empty() ?
154 0 : scheme_.length() + kSchemeIdLen);
155 if (domain_.empty()) {
158 size_t start_of_path = sub_url.find_first_of('/');
159 if (start_of_path != std::string::npos)
160 path_ = sub_url.substr(start_of_path);
164 URL::URL(const std::string& url) {
165 impl_ = new URLImpl(url);
168 std::string URL::url() const { return impl_->url(); }
169 std::string URL::scheme() const { return impl_->scheme(); }
170 std::string URL::domain() const { return impl_->domain(); }
171 int URL::port() const { return impl_->port(); }
172 std::string URL::path() const { return impl_->path(); }
178 } // namespace common