1 //===-- UriParser.cpp -------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Utility/UriParser.h" 11 12 // C Includes 13 14 // C++ Includes 15 #include <cstring> 16 17 // Other libraries and framework includes 18 // Project includes 19 #include "lldb/Host/StringConvert.h" 20 21 using namespace lldb_private; 22 23 //---------------------------------------------------------------------- 24 // UriParser::Parse 25 //---------------------------------------------------------------------- 26 bool 27 UriParser::Parse(const std::string& uri, 28 std::string& scheme, 29 std::string& hostname, 30 int& port, 31 std::string& path) 32 { 33 std::string tmp_scheme, tmp_hostname, tmp_port, tmp_path; 34 35 static const char* kSchemeSep = "://"; 36 auto pos = uri.find(kSchemeSep); 37 if (pos == std::string::npos) 38 return false; 39 40 // Extract path. 41 tmp_scheme = uri.substr(0, pos); 42 auto host_pos = pos + strlen(kSchemeSep); 43 auto path_pos = uri.find('/', host_pos); 44 if (path_pos != std::string::npos) 45 tmp_path = uri.substr(path_pos); 46 else 47 tmp_path = "/"; 48 49 auto host_port = uri.substr( 50 host_pos, ((path_pos != std::string::npos) ? path_pos : uri.size()) - host_pos); 51 52 // Extract hostname 53 if (host_port[0] == '[') 54 { 55 // hostname is enclosed with square brackets. 56 pos = host_port.find(']'); 57 if (pos == std::string::npos) 58 return false; 59 60 tmp_hostname = host_port.substr(1, pos - 1); 61 host_port.erase(0, pos + 1); 62 } 63 else 64 { 65 pos = host_port.find(':'); 66 tmp_hostname = host_port.substr(0, (pos != std::string::npos) ? pos : host_port.size()); 67 host_port.erase(0, (pos != std::string::npos) ? pos : host_port.size()); 68 } 69 70 // Extract port 71 tmp_port = host_port; 72 if (!tmp_port.empty()) 73 { 74 if (tmp_port[0] != ':') 75 return false; 76 tmp_port = tmp_port.substr(1); 77 bool success = false; 78 auto port_tmp = StringConvert::ToUInt32(tmp_port.c_str(), UINT32_MAX, 10, &success); 79 if (!success || port_tmp > 65535) 80 { 81 // there are invalid characters in port_buf 82 return false; 83 } 84 port = port_tmp; 85 } 86 else 87 port = -1; 88 89 scheme = tmp_scheme; 90 hostname = tmp_hostname; 91 path = tmp_path; 92 return true; 93 } 94 95