summaryrefslogtreecommitdiffstats
path: root/libtransport/src/hicn/transport/utils/uri.cc
blob: 33eb8b45b7746c86953cf7d471eda36519331c82 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
 * Copyright (c) 2017-2019 Cisco and/or its affiliates.
 * Licensed 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.
 */

#include <hicn/transport/errors/runtime_exception.h>
#include <hicn/transport/utils/uri.h>

namespace utils {

Uri::Uri() {}

Uri &Uri::parse(const std::string &uri) {
  if (uri.length() == 0) {
    throw errors::RuntimeException("Malformed URI.");
  }

  iterator_t uri_end = uri.end();

  // get query start
  iterator_t query_start = std::find(uri.begin(), uri_end, '?');

  // protocol
  iterator_t protocol_start = uri.begin();
  iterator_t protocol_end = std::find(protocol_start, uri_end, ':');  //"://");

  if (protocol_end != uri_end) {
    std::string prot = &*(protocol_end);
    if ((prot.length() > 3) && (prot.substr(0, 3) == "://")) {
      protocol_ = std::string(protocol_start, protocol_end);
      protocol_end += 3;  //      ://
    } else {
      protocol_end = uri.begin();  // no protocol
    }
  } else {
    protocol_end = uri.begin();  // no protocol
  }
  // host
  iterator_t host_start = protocol_end;
  iterator_t path_start =
      std::find(host_start, uri_end, '/');  // get path_start

  iterator_t host_end = std::find(
      protocol_end, (path_start != uri_end) ? path_start : query_start,
      ':');  // check for port

  locator_ = std::string(host_start, host_end);

  // port
  if ((host_end != uri_end) && ((&*(host_end))[0] == ':')) {
    host_end++;
    iterator_t port_end = (path_start != uri_end) ? path_start : query_start;
    port_ = std::string(host_end, port_end);
  }

  // path
  if (path_start != uri_end) {
    path_ = std::string(path_start, query_start);
  }
  // query
  if (query_start != uri_end) {
    query_string_ = std::string(query_start, uri.end());
  }

  return *this;
}

Uri &Uri::parseProtocolAndLocator(const std::string &locator) {
  iterator_t total_end = locator.end();

  // protocol
  iterator_t protocol_start = locator.begin();
  iterator_t protocol_end =
      std::find(protocol_start, total_end, ':');  //"://");

  if (protocol_end != total_end) {
    std::string prot = &*(protocol_end);
    if ((prot.length() > 3) && (prot.substr(0, 3) == "://")) {
      protocol_ = std::string(protocol_start, protocol_end);
      protocol_end += 3;  //      ://
    } else {
      throw errors::RuntimeException("Malformed locator. (Missing \"://\")");
    }
  } else {
    throw errors::RuntimeException("Malformed locator. No protocol specified.");
  }

  // locator
  iterator_t host_start = protocol_end;
  iterator_t host_end = std::find(protocol_end, total_end, '/');

  if (host_start == host_end) {
    throw errors::RuntimeException(
        "Malformed locator. Locator name is missing");
  }

  locator_ = std::string(host_start, host_end);

  return *this;
}

std::string Uri::getLocator() { return locator_; }

std::string Uri::getPath() { return path_; }

std::string Uri::getPort() { return port_; }

std::string Uri::getProtocol() { return protocol_; }

std::string Uri::getQueryString() { return query_string_; }

}  // end namespace utils