blob: 16e711c5c0bc29b1967a20f0827238f8a7b0deaf [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __ZOOKEEPER_URL_HPP__
#define __ZOOKEEPER_URL_HPP__
#include <string>
#include <stout/error.hpp>
#include <stout/option.hpp>
#include <stout/strings.hpp>
#include <stout/try.hpp>
#include "zookeeper/authentication.hpp"
namespace zookeeper {
// Describes a ZooKeeper URL of the form:
//
// zk://username:password@servers/path
//
// Where username:password is for the 'digest' scheme (see ZooKeeper
// documentation regarding "access controls using ACLs") and servers
// is of the form:
//
// host1:port1,host2:port2,host3:port3
//
// Note that in the future we may want to support authentication
// mechanisms other than 'digest' and have a URL of the following
// form.
//
// zk://scheme:credentials@servers/path
class URL
{
public:
// TODO(kensipe): Add support for "file://" based urls.
static Try<URL> parse(const std::string& url);
const Option<Authentication> authentication;
const std::string servers;
const std::string path;
private:
URL(const std::string& _servers,
const std::string& _path)
: servers(_servers),
path(_path) {}
URL(const std::string& credentials,
const std::string& _servers,
const std::string& _path)
: authentication(Authentication("digest", credentials)),
servers(_servers),
path(_path) {}
};
inline Try<URL> URL::parse(const std::string& url)
{
std::string s = strings::trim(url);
size_t index = s.find_first_of("zk://");
if (index != 0) {
return Error("Expecting 'zk://' at the beginning of the URL");
}
s = s.substr(5);
// Look for the trailing '/' (if any), that's where the path starts.
std::string path;
do {
index = s.find_last_of('/');
if (index == std::string::npos) {
break;
} else {
path = s.substr(index) + path;
s = s.substr(0, index);
}
} while (true);
if (path == "") {
path = "/";
}
// Look for the trailing '@' (if any), that's where servers starts.
index = s.find_last_of('@');
if (index != std::string::npos) {
return URL(s.substr(0, index), s.substr(index + 1), path);
} else {
return URL(s, path);
}
}
inline std::ostream& operator << (std::ostream& stream, const URL& url)
{
stream << "zk://";
if (url.authentication.isSome()) {
stream << url.authentication.get() << "@";
}
return stream << url.servers << url.path;
}
} // namespace zookeeper {
#endif // __ZOOKEEPER_URL_HPP__