1 //===-- UriParser.cpp -------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Utility/UriParser.h"
10 
11 #include <string>
12 
13 #include <stdint.h>
14 #include <tuple>
15 
16 using namespace lldb_private;
17 
18 //----------------------------------------------------------------------
19 // UriParser::Parse
20 //----------------------------------------------------------------------
21 bool UriParser::Parse(llvm::StringRef uri, llvm::StringRef &scheme,
22                       llvm::StringRef &hostname, int &port,
23                       llvm::StringRef &path) {
24   llvm::StringRef tmp_scheme, tmp_hostname, tmp_path;
25 
26   const llvm::StringRef kSchemeSep("://");
27   auto pos = uri.find(kSchemeSep);
28   if (pos == std::string::npos)
29     return false;
30 
31   // Extract path.
32   tmp_scheme = uri.substr(0, pos);
33   auto host_pos = pos + kSchemeSep.size();
34   auto path_pos = uri.find('/', host_pos);
35   if (path_pos != std::string::npos)
36     tmp_path = uri.substr(path_pos);
37   else
38     tmp_path = "/";
39 
40   auto host_port = uri.substr(
41       host_pos,
42       ((path_pos != std::string::npos) ? path_pos : uri.size()) - host_pos);
43 
44   // Extract hostname
45   if (!host_port.empty() && host_port[0] == '[') {
46     // hostname is enclosed with square brackets.
47     pos = host_port.find(']');
48     if (pos == std::string::npos)
49       return false;
50 
51     tmp_hostname = host_port.substr(1, pos - 1);
52     host_port = host_port.drop_front(pos + 1);
53     if (!host_port.empty() && !host_port.consume_front(":"))
54       return false;
55   } else {
56     std::tie(tmp_hostname, host_port) = host_port.split(':');
57   }
58 
59   // Extract port
60   if (!host_port.empty()) {
61     uint16_t port_value = 0;
62     if (host_port.getAsInteger(0, port_value))
63       return false;
64     port = port_value;
65   } else
66     port = -1;
67 
68   scheme = tmp_scheme;
69   hostname = tmp_hostname;
70   path = tmp_path;
71   return true;
72 }
73