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 UriParser::Parse(const std::string &uri, std::string &scheme, 27 std::string &hostname, int &port, std::string &path) { 28 std::string tmp_scheme, tmp_hostname, tmp_port, tmp_path; 29 30 static const char *kSchemeSep = "://"; 31 auto pos = uri.find(kSchemeSep); 32 if (pos == std::string::npos) 33 return false; 34 35 // Extract path. 36 tmp_scheme = uri.substr(0, pos); 37 auto host_pos = pos + strlen(kSchemeSep); 38 auto path_pos = uri.find('/', host_pos); 39 if (path_pos != std::string::npos) 40 tmp_path = uri.substr(path_pos); 41 else 42 tmp_path = "/"; 43 44 auto host_port = uri.substr( 45 host_pos, 46 ((path_pos != std::string::npos) ? path_pos : uri.size()) - host_pos); 47 48 // Extract hostname 49 if (host_port[0] == '[') { 50 // hostname is enclosed with square brackets. 51 pos = host_port.find(']'); 52 if (pos == std::string::npos) 53 return false; 54 55 tmp_hostname = host_port.substr(1, pos - 1); 56 host_port.erase(0, pos + 1); 57 } else { 58 pos = host_port.find(':'); 59 tmp_hostname = host_port.substr( 60 0, (pos != std::string::npos) ? pos : host_port.size()); 61 host_port.erase(0, (pos != std::string::npos) ? pos : host_port.size()); 62 } 63 64 // Extract port 65 tmp_port = host_port; 66 if (!tmp_port.empty()) { 67 if (tmp_port[0] != ':') 68 return false; 69 tmp_port = tmp_port.substr(1); 70 bool success = false; 71 auto port_tmp = 72 StringConvert::ToUInt32(tmp_port.c_str(), UINT32_MAX, 10, &success); 73 if (!success || port_tmp > 65535) { 74 // there are invalid characters in port_buf 75 return false; 76 } 77 port = port_tmp; 78 } else 79 port = -1; 80 81 scheme = tmp_scheme; 82 hostname = tmp_hostname; 83 path = tmp_path; 84 return true; 85 } 86