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() : port_(0) {
81 URLImpl::URLImpl(const std::string& url) : port_(0) {
86 if (!ExtractScheme()) {
92 if (scheme_ != kSchemeTypeFile)
98 bool URLImpl::ExtractScheme() {
99 size_t end_of_scheme = 0;
100 if (url_.find("://") != std::string::npos) {
101 end_of_scheme = url_.find("://");
102 std::string scheme = url_.substr(0, end_of_scheme);
103 std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower);
111 void URLImpl::ExtractDomain() {
112 size_t start_of_domain = scheme_.empty() ?
113 0 : scheme_.length() + kSchemeIdLen;
114 size_t end_of_domain = url_.find_first_of('/', start_of_domain);
115 size_t at = url_.find_first_of('@', start_of_domain);
116 if (at < end_of_domain) {
117 start_of_domain = at + 1;
120 url_.substr(start_of_domain, end_of_domain == std::string::npos ?
121 std::string::npos : end_of_domain - start_of_domain);
122 LOGGER(INFO) << "Extract Domain is " << domain_;
125 void URLImpl::ExtractDomainPort() {
127 std::string domain = domain_;
129 // Decide start position to find port considering IPv6 case
130 size_t start_pos = domain.find('@');
131 start_pos = (start_pos != std::string::npos) ? start_pos + 1 : 0;
132 if (domain[start_pos] == '[')
133 start_pos = domain.find(']', start_pos+1);
135 size_t port_separator =
136 domain.find_first_of(':', start_pos != std::string::npos ? start_pos : 0);
137 if (port_separator != std::string::npos) {
138 domain_ = domain.substr(0, port_separator);
139 std::string port = domain.substr(port_separator+1);
141 port_ = GetDefaultPort(scheme_);
144 port_ = std::stoi(port);
146 port_ = GetDefaultPort(scheme_);
151 port_ = GetDefaultPort(scheme_);
155 void URLImpl::ExtractPath() {
156 std::string sub_url = url_.substr(scheme_.empty() ?
157 0 : scheme_.length() + kSchemeIdLen);
158 if (domain_.empty()) {
161 size_t start_of_path = sub_url.find_first_of('/');
162 if (start_of_path != std::string::npos)
163 path_ = sub_url.substr(start_of_path);
167 URL::URL(const std::string& url) {
168 impl_ = new URLImpl(url);
171 std::string URL::url() const { return impl_->url(); }
172 std::string URL::scheme() const { return impl_->scheme(); }
173 std::string URL::domain() const { return impl_->domain(); }
174 int URL::port() const { return impl_->port(); }
175 std::string URL::path() const { return impl_->path(); }
181 } // namespace common