blob: cc6c8c8f72fd345d1f6ad2f7e45f5e306efa98df [file] [log] [blame]
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "face-uri.hpp"
8#include "core/logger.hpp"
9#include <boost/regex.hpp>
10
11NFD_LOG_INIT("FaceUri");
12
13namespace nfd {
14
15FaceUri::FaceUri(const std::string& uri)
16{
Junxiao Shi61e3cc52014-03-03 20:40:28 -070017 if (!parse(uri)) {
18 throw Error("Malformed URI: " + uri);
19 }
20}
21
22FaceUri::FaceUri(const char* uri)
23{
24 if (!parse(uri)) {
25 throw Error("Malformed URI: " + std::string(uri));
26 }
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080027}
28
29bool
30FaceUri::parse(const std::string& uri)
31{
32 m_scheme.clear();
Junxiao Shi61e3cc52014-03-03 20:40:28 -070033 m_host.clear();
34 m_isV6 = false;
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080035 m_port.clear();
Junxiao Shi61e3cc52014-03-03 20:40:28 -070036 m_path.clear();
37
38 boost::regex protocolExp("(\\w+\\d?)://([^/]*)(\\/[^?]*)?");
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080039 boost::smatch protocolMatch;
Junxiao Shi61e3cc52014-03-03 20:40:28 -070040 if (!boost::regex_match(uri, protocolMatch, protocolExp)) {
41 return false;
42 }
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080043 m_scheme = protocolMatch[1];
Junxiao Shi61e3cc52014-03-03 20:40:28 -070044 m_path = protocolMatch[3];
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080045
Junxiao Shi61e3cc52014-03-03 20:40:28 -070046 const std::string& authority = protocolMatch[2];
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080047
Junxiao Shi61e3cc52014-03-03 20:40:28 -070048 boost::regex v6Exp("^\\[(([a-fA-F0-9:]+))\\](:(\\d+))?$"); // [host]:port
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080049 boost::regex v4Exp("^((\\d+\\.){3}\\d+)(:(\\d+))?$");
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +000050 boost::regex hostExp("^(([^:]*))(:(\\d+))?$"); // host:port
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080051
52 boost::smatch match;
Junxiao Shi61e3cc52014-03-03 20:40:28 -070053 m_isV6 = boost::regex_match(authority, match, v6Exp);
54 if (m_isV6 ||
55 boost::regex_match(authority, match, v4Exp) ||
56 boost::regex_match(authority, match, hostExp)) {
57 m_host = match[1];
58 m_port = match[4];
59 }
60 else {
61 if (m_path.empty()) {
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080062 return false;
63 }
Junxiao Shi61e3cc52014-03-03 20:40:28 -070064 }
65
66 NFD_LOG_DEBUG("URI [" << uri << "] parsed into: " <<
67 m_scheme << ", " << m_host << ", " << m_port << ", " << m_path);
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080068 return true;
69}
70
Junxiao Shi61e3cc52014-03-03 20:40:28 -070071FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint)
72{
73 m_isV6 = endpoint.address().is_v6();
74 m_scheme = m_isV6 ? "tcp6" : "tcp4";
75 m_host = endpoint.address().to_string();
76 m_port = boost::lexical_cast<std::string>(endpoint.port());
77}
78
79FaceUri::FaceUri(const boost::asio::ip::udp::endpoint& endpoint)
80{
81 m_isV6 = endpoint.address().is_v6();
82 m_scheme = m_isV6 ? "udp6" : "udp4";
83 m_host = endpoint.address().to_string();
84 m_port = boost::lexical_cast<std::string>(endpoint.port());
85}
86
87FaceUri::FaceUri(const boost::asio::local::stream_protocol::endpoint& endpoint)
88 : m_isV6(false)
89{
90 m_scheme = "unix";
91 m_path = endpoint.path();
92}
93
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080094} // namespace nfd