1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "js_uri.h" 17 namespace OHOS::Uri { 18 std::bitset<MAX_BIT_SIZE> g_ruleAlpha; 19 std::bitset<MAX_BIT_SIZE> g_ruleScheme; 20 std::bitset<MAX_BIT_SIZE> g_ruleUrlc; 21 std::bitset<MAX_BIT_SIZE> g_rulePath; 22 std::bitset<MAX_BIT_SIZE> g_ruleUserInfo; 23 std::bitset<MAX_BIT_SIZE> g_ruleDigit; 24 std::bitset<MAX_BIT_SIZE> g_rulePort; PreliminaryWork() const25 void Uri::PreliminaryWork() const 26 { 27 std::string digitAggregate = "0123456789"; 28 for (size_t i = 0; i < digitAggregate.size(); ++i) { 29 g_ruleDigit.set(digitAggregate[i]); 30 } 31 32 std::string alphasAggregate = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 33 for (size_t i = 0; i < alphasAggregate.size(); ++i) { 34 g_ruleAlpha.set(alphasAggregate[i]); 35 } 36 37 std::string schemeAggregate = digitAggregate + alphasAggregate + "+-.| _-~!$&=,;'(){}*"; 38 for (size_t i = 0; i < schemeAggregate.size(); ++i) { 39 g_ruleScheme.set(schemeAggregate[i]); 40 } 41 42 std::string uricAggregate = schemeAggregate + ";/?:@&=$,[]_!~*'()%\""; 43 for (size_t i = 0; i < uricAggregate.size(); ++i) { 44 g_ruleUrlc.set(uricAggregate[i]); 45 } 46 47 std::string pathAggregate = schemeAggregate + ";/:@&=$,_!~*'()%"; 48 for (size_t i = 0; i < pathAggregate.size(); ++i) { 49 g_rulePath.set(pathAggregate[i]); 50 } 51 52 std::string userInfoAggregate = schemeAggregate + ";:&=$,_!~*'()%"; 53 for (size_t i = 0; i < userInfoAggregate.size(); ++i) { 54 g_ruleUserInfo.set(userInfoAggregate[i]); 55 } 56 57 std::string portAggregate = digitAggregate + alphasAggregate + ".:@-;&=+$,-_!~*'()"; 58 for (size_t i = 0; i < portAggregate.size(); ++i) { 59 g_rulePort.set(portAggregate[i]); 60 } 61 } 62 Uri(const std::string input)63 Uri::Uri(const std::string input) 64 { 65 PreliminaryWork(); 66 errStr_ = ""; 67 if (input.empty()) { 68 errStr_ = "uri is empty"; 69 return; 70 } 71 inputUri_ = input; 72 AnalysisUri(); 73 } 74 AssignSchemeSpecificPart()75 void Uri::AssignSchemeSpecificPart() 76 { 77 uriData_.SchemeSpecificPart.reserve(data_.length() + uriData_.query.length() + 1); 78 uriData_.SchemeSpecificPart.append(data_); 79 if (!uriData_.query.empty()) { 80 uriData_.SchemeSpecificPart.append("?"); 81 uriData_.SchemeSpecificPart.append(uriData_.query); 82 } 83 } 84 AnalysisUri()85 void Uri::AnalysisUri() 86 { 87 data_ = inputUri_; 88 size_t pos = data_.find('#'); // Fragment 89 if (pos != std::string::npos) { 90 AnalysisFragment(pos); 91 if (!errStr_.empty()) { 92 return; 93 } 94 } 95 pos = data_.find('?'); // Query 96 if (pos != std::string::npos) { 97 AnalysisQuery(pos); 98 if (!errStr_.empty()) { 99 return; 100 } 101 } 102 pos = data_.find(':'); // Scheme 103 if (pos != std::string::npos) { 104 AnalysisScheme(pos); 105 if (!errStr_.empty()) { 106 return; 107 } 108 } else { 109 SpecialPath(); 110 if (!errStr_.empty()) { 111 return; 112 } 113 AssignSchemeSpecificPart(); 114 return; 115 } 116 pos = data_.find("//"); // userInfo path host port ipv4 or ipv6 117 if (pos != std::string::npos && pos == 0) { 118 AssignSchemeSpecificPart(); 119 data_ = data_.substr(2); // 2:Intercept the string from the second subscript 120 AnalysisHostAndPath(); 121 if (!errStr_.empty()) { 122 return; 123 } 124 } else if (data_[0] == '/') { 125 uriData_.path = data_; 126 AssignSchemeSpecificPart(); 127 data_ = ""; 128 } else { 129 AssignSchemeSpecificPart(); 130 uriData_.query = ""; 131 data_ = ""; 132 } 133 } 134 CheckCharacter(std::string data,std::bitset<MAX_BIT_SIZE> rule,bool flag) const135 bool Uri::CheckCharacter(std::string data, std::bitset<MAX_BIT_SIZE> rule, bool flag) const 136 { 137 size_t dataLen = data.size(); 138 for (size_t i = 0; i < dataLen; ++i) { 139 if (static_cast<int>(data[i]) >= 0 && static_cast<int>(data[i]) < 128) { // 128:ASCII Max Number 140 bool isLegal = rule.test(data[i]); 141 if (!isLegal) { 142 return false; 143 } 144 } else if (!flag) { 145 return false; 146 } 147 } 148 return true; 149 } 150 SpecialPath()151 void Uri::SpecialPath() 152 { 153 if (!CheckCharacter(data_, g_rulePath, true)) { 154 errStr_ = "SpecialPath does not conform to the rule"; 155 return; 156 } 157 uriData_.path = data_; 158 data_ = ""; 159 } 160 AnalysisFragment(size_t pos)161 void Uri::AnalysisFragment(size_t pos) 162 { 163 if (pos == 0) { 164 errStr_ = "#It can't be the first"; 165 return; 166 } 167 std::string fragment = data_.substr(pos + 1); 168 if (!CheckCharacter(fragment, g_ruleUrlc, true)) { 169 errStr_ = "Fragment does not conform to the rule"; 170 return; 171 } 172 uriData_.fragment = fragment; 173 data_ = data_.substr(0, pos); 174 } 175 AnalysisQuery(size_t pos)176 void Uri::AnalysisQuery(size_t pos) 177 { 178 std::string query = data_.substr(pos + 1); 179 if (!CheckCharacter(query, g_ruleUrlc, true)) { 180 errStr_ = "Query does not conform to the rule"; 181 return; 182 } 183 uriData_.query = query; 184 data_ = data_.substr(0, pos); 185 } 186 AnalysisScheme(size_t pos)187 void Uri::AnalysisScheme(size_t pos) 188 { 189 size_t slashPos = data_.find('/'); 190 if (slashPos != std::string::npos && slashPos < pos) { 191 SpecialPath(); 192 uriData_.SchemeSpecificPart.reserve(uriData_.path.length() + uriData_.query.length() + 1); 193 uriData_.SchemeSpecificPart.append(uriData_.path); 194 uriData_.SchemeSpecificPart.append("?"); 195 uriData_.SchemeSpecificPart.append(uriData_.query); 196 data_ = ""; 197 } else { 198 if ((static_cast<int>(data_[0]) >= 0 && static_cast<int>(data_[0]) < MAX_BIT_SIZE) && 199 !g_ruleAlpha.test(data_[0])) { 200 errStr_ = "Scheme the first character must be a letter"; 201 return; 202 } 203 std::string scheme = data_.substr(0, pos); 204 if (!CheckCharacter(scheme, g_ruleScheme, false)) { 205 errStr_ = "scheme does not conform to the rule"; 206 return; 207 } 208 uriData_.scheme = scheme; 209 data_ = data_.substr(pos + 1); 210 } 211 } 212 AnalysisHost(bool isLawfulProt)213 void Uri::AnalysisHost(bool isLawfulProt) 214 { 215 // find ipv4 or ipv6 or host 216 if (data_[0] == '[') { 217 if (data_[data_.size() - 1] == ']') { 218 // IPV6 219 if (!isLawfulProt) { 220 errStr_ = "Prot does not conform to the rule"; 221 return; 222 } 223 AnalysisIPV6(); 224 } else { 225 errStr_ = "IPv6 is missing a closing bracket"; 226 return; 227 } 228 } else { 229 if (data_.find('[') != std::string::npos || data_.find(']') != std::string::npos) { 230 errStr_ = "host does not conform to the rule"; 231 return; 232 } 233 // ipv4 234 if (!isLawfulProt || !AnalysisIPV4()) { 235 uriData_.port = -1; 236 uriData_.host = ""; 237 uriData_.userInfo = ""; 238 } 239 } 240 } 241 AnalysisHostAndPath()242 void Uri::AnalysisHostAndPath() 243 { 244 if (data_.empty()) { 245 return; 246 } 247 // find path 248 size_t pos = data_.find('/'); 249 if (pos != std::string::npos) { 250 AnalysisPath(pos); 251 if (!errStr_.empty()) { 252 return; 253 } 254 } 255 uriData_.authority = data_; 256 // find UserInfo 257 pos = data_.find('@'); 258 if (pos != std::string::npos) { 259 AnalysisUserInfo(pos); 260 if (!errStr_.empty()) { 261 return; 262 } 263 } 264 bool isLawfulProt = true; 265 // find port 266 pos = data_.rfind(':'); 267 if (pos != std::string::npos) { 268 size_t pos1 = data_.rfind(']'); 269 if (pos1 == std::string::npos || pos > pos1) { 270 isLawfulProt = AnalysisPort(pos); 271 } 272 if (!errStr_.empty()) { 273 return; 274 } 275 } 276 AnalysisHost(isLawfulProt); 277 } 278 AnalysisPath(size_t pos)279 void Uri::AnalysisPath(size_t pos) 280 { 281 std::string path = data_.substr(pos); 282 if (!CheckCharacter(path, g_rulePath, true)) { 283 errStr_ = "path does not conform to the rule"; 284 return; 285 } 286 uriData_.path = path; 287 data_ = data_.substr(0, pos); 288 } 289 AnalysisUserInfo(size_t pos)290 void Uri::AnalysisUserInfo(size_t pos) 291 { 292 std::string userInfo = data_.substr(0, pos); 293 if (!CheckCharacter(userInfo, g_ruleUserInfo, true)) { 294 errStr_ = "userInfo does not conform to the rule"; 295 return; 296 } 297 uriData_.userInfo = userInfo; 298 data_ = data_.substr(pos + 1); 299 } 300 AnalysisPort(size_t pos)301 bool Uri::AnalysisPort(size_t pos) 302 { 303 std::string port = data_.substr(pos + 1); 304 if (!CheckCharacter(port, g_rulePort, true)) { 305 errStr_ = "port does not conform to the rule"; 306 return false; 307 } else if (CheckCharacter(port, g_ruleDigit, false)) { 308 if (port.size() == 0 || port.size() > 10) { // 10:The maximum number of bits for int value 309 return false; 310 } 311 double tempPort = std::strtod(port.c_str(), nullptr); 312 if (tempPort < 0 || tempPort > INT32_MAX) { 313 return false; 314 } 315 uriData_.port = static_cast<int>(tempPort); 316 data_ = data_.substr(0, pos); 317 return true; 318 } else { 319 data_ = data_.substr(0, pos); 320 return false; 321 } 322 return false; 323 } 324 AnalysisIPV4()325 bool Uri::AnalysisIPV4() 326 { 327 std::regex ipv4("((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"); 328 std::regex hostname("(([a-zA-Z0-9]([a-zA-Z0-9\\-~_|\\+{}!$&=,;:'()\\*\\s]*[a-zA-Z0-9])?\\.)+" 329 "([a-zA-Z]([a-zA-Z0-9\\-~_|\\+{}!$&=,;:'()\\*\\s]*" 330 "[a-zA-Z0-9\\-~_|\\+{}!$&=,;:'()\\*\\s])?))|" 331 "([a-zA-Z0-9]([a-zA-Z0-9\\-~_|\\+{}!$&=,;:'()\\*\\s]*[a-zA-Z0-9])?)"); 332 bool isIpv4 = std::regex_match(data_, ipv4); 333 bool isHosName = std::regex_match(data_, hostname); 334 if (!isIpv4 && !isHosName) { 335 return false; 336 } else { 337 uriData_.host = data_; 338 data_ = ""; 339 return true; 340 } 341 } 342 AnalysisIPV6()343 void Uri::AnalysisIPV6() 344 { 345 std::string str = data_.substr(1, data_.size() - 2); // 2:Intercept the string from the second subscript 346 std::regex ipv6("(::|(:((:[0-9A-Fa-f]{1,4}){1,7}))|(([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|" 347 "(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|:))|(([0-9A-Fa-f]{1,4}:){2}" 348 "(((:[0-9A-Fa-f]{1,4}){1,5})|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})" 349 "|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|:))|(([0-9A-Fa-f]{1,4}:){5}" 350 "(((:[0-9A-Fa-f]{1,4}){1,2})|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|" 351 "(((:(:[0-9A-Fa-f]{1,4}){0,5}:)|(([0-9A-Fa-f]{1,4}:){1}(:[0-9A-Fa-f]{1,4}){0,4}:)" 352 "|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}:)|(([0-9A-Fa-f]{1,4}:){3}" 353 "(:[0-9A-Fa-f]{1,4}){0,2}:)|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4})?:)|" 354 "(([0-9A-Fa-f]{1,4}:){5}:)|(([0-9A-Fa-f]{1,4}:){6}))((25[0-5]|2[0-4]\\d|1\\d{2}|" 355 "[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)))(%[a-zA-Z0-9._]+)?"); 356 if (!std::regex_match(str, ipv6)) { 357 errStr_ = "ipv6 does not conform to the rule"; 358 return; 359 } 360 uriData_.host = data_; 361 data_ = ""; 362 } 363 Equals(const Uri other) const364 bool Uri::Equals(const Uri other) const 365 { 366 if (uriData_.port != other.uriData_.port) { 367 return false; 368 } 369 if (uriData_.scheme != other.uriData_.scheme) { 370 return false; 371 } 372 if (uriData_.userInfo != other.uriData_.userInfo) { 373 return false; 374 } 375 if (uriData_.host != other.uriData_.host) { 376 return false; 377 } 378 if (uriData_.query != other.uriData_.query) { 379 return false; 380 } 381 if (uriData_.fragment != other.uriData_.fragment) { 382 return false; 383 } 384 if (uriData_.path != other.uriData_.path) { 385 return false; 386 } 387 if (uriData_.authority != other.uriData_.authority) { 388 return false; 389 } 390 if (uriData_.SchemeSpecificPart != other.uriData_.SchemeSpecificPart) { 391 return false; 392 } 393 return true; 394 } 395 ToString() const396 std::string Uri::ToString() const 397 { 398 return inputUri_; 399 } 400 IsAbsolute() const401 bool Uri::IsAbsolute() const 402 { 403 return !uriData_.scheme.empty(); 404 } 405 IsRelative() const406 bool Uri::IsRelative() const 407 { 408 return uriData_.scheme.empty(); 409 } 410 IsOpaque() const411 bool Uri::IsOpaque() const 412 { 413 return !IsHierarchical(); 414 } 415 IsHierarchical() const416 bool Uri::IsHierarchical() const 417 { 418 size_t index = inputUri_.find(':'); 419 if (index == std::string::npos) { 420 return true; 421 } 422 if (inputUri_.length() == index + 1) { 423 return false; 424 } 425 return inputUri_[index + 1] == '/'; 426 } 427 AddQueryValue(const std::string key,const std::string value) const428 std::string Uri::AddQueryValue(const std::string key, const std::string value) const 429 { 430 return BuildUriString("query", key + "=" + value); 431 } 432 AddSegment(const std::string pathSegment) const433 std::string Uri::AddSegment(const std::string pathSegment) const 434 { 435 return BuildUriString("segment", pathSegment); 436 } 437 BuildUriString(const std::string str,const std::string param) const438 std::string Uri::BuildUriString(const std::string str, const std::string param) const 439 { 440 std::string result = ""; 441 if (!uriData_.scheme.empty()) { 442 result += uriData_.scheme + ":"; 443 } 444 if (!uriData_.authority.empty()) { 445 result += "//" + uriData_.authority; 446 } 447 if (!uriData_.path.empty()) { 448 result += uriData_.path ; 449 } 450 if (str == "segment") { 451 if (result.back() == '/') { 452 result += param; 453 } else { 454 result += "/" + param; 455 } 456 } 457 if (str != "clearquery") { 458 if (uriData_.query.empty()) { 459 if (str == "query") { 460 result += "?" + param; 461 } 462 } else { 463 result += "?" + uriData_.query; 464 if (str == "query") { 465 result += "&" + param; 466 } 467 } 468 } 469 if (!uriData_.fragment.empty()) { 470 result += "#" + uriData_.fragment; 471 } 472 return result; 473 } 474 GetLastSegment() const475 std::string Uri::GetLastSegment() const 476 { 477 std::string trimmedPath = uriData_.path; 478 if (trimmedPath.empty()) { 479 return trimmedPath; 480 } 481 if (trimmedPath.back() == '/') { 482 trimmedPath.pop_back(); 483 } 484 485 size_t pos = trimmedPath.rfind('/'); 486 if (pos != std::string::npos) { 487 return trimmedPath.substr(pos + 1); 488 } 489 490 return trimmedPath; 491 } 492 IsFailed() const493 std::string Uri::IsFailed() const 494 { 495 return errStr_; 496 } 497 Normalize() const498 std::string Uri::Normalize() const 499 { 500 std::vector<std::string> temp; 501 size_t pathLen = uriData_.path.size(); 502 if (pathLen == 0) { 503 return this->inputUri_; 504 } 505 size_t pos = 0; 506 size_t left = 0; 507 while ((pos = uriData_.path.find('/', left)) != std::string::npos) { 508 temp.push_back(uriData_.path.substr(left, pos - left)); 509 left = pos + 1; 510 } 511 if (left != pathLen) { 512 temp.push_back(uriData_.path.substr(left)); 513 } 514 size_t tempLen = temp.size(); 515 std::vector<std::string> normalizeTemp; 516 for (size_t i = 0; i < tempLen; ++i) { 517 if (!temp[i].empty() && !(temp[i] == ".") && !(temp[i] == "..")) { 518 normalizeTemp.push_back(temp[i]); 519 } 520 if (temp[i] == "..") { 521 if (!normalizeTemp.empty() && normalizeTemp.back() != "..") { 522 normalizeTemp.pop_back(); 523 } else { 524 normalizeTemp.push_back(temp[i]); 525 } 526 } 527 } 528 std::string normalizePath = ""; 529 tempLen = normalizeTemp.size(); 530 if (tempLen == 0) { 531 normalizePath = "/"; 532 } else { 533 for (size_t i = 0; i < tempLen; ++i) { 534 normalizePath += "/" + normalizeTemp[i]; 535 } 536 } 537 return Split(normalizePath); 538 } 539 540 Split(const std::string & path) const541 std::string Uri::Split(const std::string &path) const 542 { 543 std::string normalizeUri = ""; 544 if (!uriData_.scheme.empty()) { 545 normalizeUri += uriData_.scheme + ":"; 546 } 547 if (uriData_.path.empty()) { 548 normalizeUri += uriData_.SchemeSpecificPart; 549 } else { 550 if (!uriData_.host.empty()) { 551 normalizeUri += "//"; 552 if (!uriData_.userInfo.empty()) { 553 normalizeUri += uriData_.userInfo + "@"; 554 } 555 normalizeUri += uriData_.host; 556 if (uriData_.port != -1) { 557 normalizeUri += ":" + std::to_string(uriData_.port); 558 } 559 } else if (!uriData_.authority.empty()) { 560 normalizeUri += "//" + uriData_.authority; 561 } 562 normalizeUri += path; 563 } 564 if (!uriData_.query.empty()) { 565 normalizeUri += "?" + uriData_.query; 566 } 567 if (!uriData_.fragment.empty()) { 568 normalizeUri += "#" + uriData_.fragment; 569 } 570 return normalizeUri; 571 } 572 UpdateToString() const573 std::string Uri::UpdateToString() const 574 { 575 std::string uriStr = ""; 576 bool addQuery = false; 577 if (!uriData_.scheme.empty()) { 578 uriStr += uriData_.scheme + ":"; 579 } 580 if (uriData_.path.empty()) { 581 uriStr += uriData_.SchemeSpecificPart; 582 addQuery = true; 583 } else { 584 if (!uriData_.host.empty()) { 585 uriStr += "//"; 586 if (!uriData_.userInfo.empty()) { 587 uriStr += uriData_.userInfo + "@"; 588 } 589 uriStr += uriData_.host; 590 if (uriData_.port != -1) { 591 uriStr += ":" + std::to_string(uriData_.port); 592 } 593 } else if (!uriData_.authority.empty()) { 594 uriStr += "//" + uriData_.authority; 595 } 596 if (!uriData_.path.empty()) { 597 uriData_.path[0] == '/' ? (uriStr += uriData_.path) : (uriStr += "/" + uriData_.path); 598 } 599 } 600 if (!uriData_.query.empty() && !addQuery) { 601 uriStr += "?" + uriData_.query; 602 } 603 if (!uriData_.fragment.empty()) { 604 uriStr += "#" + uriData_.fragment; 605 } 606 return uriStr; 607 } 608 GetScheme() const609 std::string Uri::GetScheme() const 610 { 611 return uriData_.scheme; 612 } 613 SetScheme(const std::string_view Scheme)614 void Uri::SetScheme(const std::string_view Scheme) 615 { 616 if ((static_cast<int>(Scheme[0]) >= 0 && static_cast<int>(Scheme[0]) < MAX_BIT_SIZE) && 617 !g_ruleAlpha.test(Scheme[0])) { 618 errStr_ = "Scheme the first character must be a letter"; 619 return; 620 } 621 622 std::string temp = ""; 623 size_t pos = Scheme.find(':'); 624 if (pos != std::string_view::npos) { 625 temp = std::string(Scheme.substr(0, pos)); 626 } else { 627 temp = std::string(Scheme); 628 } 629 630 if (!CheckCharacter(temp, g_ruleScheme, false)) { 631 errStr_ = "scheme does not conform to the rule"; 632 return; 633 } 634 uriData_.scheme = temp; 635 inputUri_ = UpdateToString(); 636 } 637 UpdateAuthority()638 void Uri::UpdateAuthority() 639 { 640 std::string temp = uriData_.userInfo; 641 if (!uriData_.userInfo.empty()) { 642 temp.append("@"); 643 } 644 temp += uriData_.host; 645 if (uriData_.port != -1) { 646 temp += ":" + std::to_string(uriData_.port); 647 } 648 uriData_.authority = temp; 649 } 650 UpdateSsp()651 void Uri::UpdateSsp() 652 { 653 std::string temp = ""; 654 if (!uriData_.authority.empty()) { 655 temp += "//" + uriData_.authority; 656 } 657 if (!uriData_.path.empty()) { 658 uriData_.path[0] == '/' ? (temp += uriData_.path) : (temp += "/" + uriData_.path); 659 } 660 661 if (!uriData_.query.empty()) { 662 temp += "?" + uriData_.query; 663 } 664 uriData_.SchemeSpecificPart = temp; 665 } 666 SetUserInfo(const std::string userInfo)667 void Uri::SetUserInfo(const std::string userInfo) 668 { 669 if (uriData_.host.empty() || (!CheckCharacter(userInfo, g_ruleUserInfo, true))) { 670 errStr_ = "userInfo does not conform to the rule"; 671 return; 672 } 673 uriData_.userInfo = userInfo; 674 UpdateAuthority(); 675 UpdateSsp(); 676 inputUri_ = UpdateToString(); 677 } 678 SetPath(const std::string pathStr)679 void Uri::SetPath(const std::string pathStr) 680 { 681 if (!CheckCharacter(pathStr, g_rulePath, true)) { 682 errStr_ = "pathStr does not conform to the rule"; 683 return; 684 } 685 uriData_.path = pathStr; 686 UpdateSsp(); 687 inputUri_ = UpdateToString(); 688 } 689 SetQuery(const std::string queryStr)690 void Uri::SetQuery(const std::string queryStr) 691 { 692 if (!CheckCharacter(queryStr, g_ruleUrlc, true)) { 693 errStr_ = "QueryStr does not conform to the rule"; 694 return; 695 } 696 uriData_.query = queryStr; 697 UpdateSsp(); 698 inputUri_ = UpdateToString(); 699 } 700 SetFragment(const std::string fragmentStr)701 void Uri::SetFragment(const std::string fragmentStr) 702 { 703 if (!CheckCharacter(fragmentStr, g_ruleUrlc, true)) { 704 errStr_ = "Fragment does not conform to the rule"; 705 return; 706 } 707 uriData_.fragment = fragmentStr; 708 inputUri_ = UpdateToString(); 709 } 710 SetAuthority(const std::string authorityStr)711 void Uri::SetAuthority(const std::string authorityStr) 712 { 713 uriData_.port = -1; 714 uriData_.host = ""; 715 uriData_.userInfo = ""; 716 uriData_.authority = authorityStr; 717 data_ = authorityStr; 718 // find UserInfo 719 size_t pos = data_.find('@'); 720 if (pos != std::string::npos) { 721 std::string userStr = data_.substr(0, pos); 722 data_ = data_.substr(pos + 1); 723 if (!CheckCharacter(userStr, g_ruleUserInfo, true)) { 724 errStr_ = "userInfo does not conform to the rule"; 725 return; 726 } 727 uriData_.userInfo = userStr; 728 } 729 730 bool isLawfulProt = true; 731 // find port 732 pos = data_.rfind(':'); 733 if (pos != std::string::npos) { 734 size_t pos1 = data_.rfind(']'); 735 if (pos1 == std::string::npos || pos > pos1) { 736 isLawfulProt = AnalysisPort(pos); 737 } 738 if (!errStr_.empty()) { 739 return; 740 } 741 } 742 AnalysisHost(isLawfulProt); 743 UpdateSsp(); 744 inputUri_ = UpdateToString(); 745 } 746 SetSsp(const std::string sspStr)747 void Uri::SetSsp(const std::string sspStr) 748 { 749 uriData_.authority = ""; 750 uriData_.port = -1; 751 uriData_.host = ""; 752 uriData_.userInfo = ""; 753 uriData_.query = ""; 754 uriData_.path = ""; 755 uriData_.SchemeSpecificPart = ""; 756 data_ = sspStr; 757 size_t pos = data_.find('?'); // Query 758 if (pos != std::string::npos) { 759 AnalysisQuery(pos); 760 } 761 pos = data_.find("//"); // userInfo path host port ipv4 or ipv6 762 if (pos != std::string::npos && pos == 0) { 763 AssignSchemeSpecificPart(); 764 data_ = data_.substr(2); // 2:Intercept the string from the second subscript 765 AnalysisHostAndPath(); 766 } else if (data_[0] == '/') { 767 uriData_.path = data_; 768 AssignSchemeSpecificPart(); 769 data_ = ""; 770 } else { 771 AssignSchemeSpecificPart(); 772 uriData_.path = ""; 773 uriData_.query = ""; 774 data_ = ""; 775 } 776 inputUri_ = UpdateToString(); 777 } 778 GetAuthority() const779 std::string Uri::GetAuthority() const 780 { 781 return uriData_.authority; 782 } 783 GetSsp() const784 std::string Uri::GetSsp() const 785 { 786 return uriData_.SchemeSpecificPart; 787 } 788 GetUserinfo() const789 std::string Uri::GetUserinfo() const 790 { 791 return uriData_.userInfo; 792 } 793 GetHost() const794 std::string Uri::GetHost() const 795 { 796 return uriData_.host; 797 } 798 GetPort() const799 std::string Uri::GetPort() const 800 { 801 return std::to_string(uriData_.port); 802 } 803 GetPath() const804 std::string Uri::GetPath() const 805 { 806 return uriData_.path; 807 } 808 GetQuery() const809 std::string Uri::GetQuery() const 810 { 811 return uriData_.query; 812 } 813 GetFragment() const814 std::string Uri::GetFragment() const 815 { 816 return uriData_.fragment; 817 } 818 ClearQuery() const819 std::string Uri::ClearQuery() const 820 { 821 return BuildUriString("clearquery", ""); 822 } 823 } // namespace OHOS::Uri 824