| 6530 | } |
| 6531 | |
| 6532 | inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) { |
| 6533 | if (req.redirect_count_ == 0) { |
| 6534 | error = Error::ExceedRedirectCount; |
| 6535 | return false; |
| 6536 | } |
| 6537 | |
| 6538 | auto location = res.get_header_value("location"); |
| 6539 | if (location.empty()) { return false; } |
| 6540 | |
| 6541 | const static std::regex re( |
| 6542 | R"((?:(https?):)?(?://(?:\[([\d:]+)\]|([^:/?#]+))(?::(\d+))?)?([^?#]*)(\?[^#]*)?(?:#.*)?)"); |
| 6543 | |
| 6544 | std::smatch m; |
| 6545 | if (!std::regex_match(location, m, re)) { return false; } |
| 6546 | |
| 6547 | auto scheme = is_ssl() ? "https" : "http"; |
| 6548 | |
| 6549 | auto next_scheme = m[1].str(); |
| 6550 | auto next_host = m[2].str(); |
| 6551 | if (next_host.empty()) { next_host = m[3].str(); } |
| 6552 | auto port_str = m[4].str(); |
| 6553 | auto next_path = m[5].str(); |
| 6554 | auto next_query = m[6].str(); |
| 6555 | |
| 6556 | auto next_port = port_; |
| 6557 | if (!port_str.empty()) { |
| 6558 | next_port = std::stoi(port_str); |
| 6559 | } else if (!next_scheme.empty()) { |
| 6560 | next_port = next_scheme == "https" ? 443 : 80; |
| 6561 | } |
| 6562 | |
| 6563 | if (next_scheme.empty()) { next_scheme = scheme; } |
| 6564 | if (next_host.empty()) { next_host = host_; } |
| 6565 | if (next_path.empty()) { next_path = "/"; } |
| 6566 | |
| 6567 | auto path = detail::decode_url(next_path, true) + next_query; |
| 6568 | |
| 6569 | if (next_scheme == scheme && next_host == host_ && next_port == port_) { |
| 6570 | return detail::redirect(*this, req, res, path, location, error); |
| 6571 | } else { |
| 6572 | if (next_scheme == "https") { |
| 6573 | #ifdef CPPHTTPLIB_OPENSSL_SUPPORT |
| 6574 | SSLClient cli(next_host.c_str(), next_port); |
| 6575 | cli.copy_settings(*this); |
| 6576 | if (ca_cert_store_) { cli.set_ca_cert_store(ca_cert_store_); } |
| 6577 | return detail::redirect(cli, req, res, path, location, error); |
| 6578 | #else |
| 6579 | return false; |
| 6580 | #endif |
| 6581 | } else { |
| 6582 | ClientImpl cli(next_host.c_str(), next_port); |
| 6583 | cli.copy_settings(*this); |
| 6584 | return detail::redirect(cli, req, res, path, location, error); |
| 6585 | } |
| 6586 | } |
| 6587 | } |
| 6588 | |
| 6589 | inline bool ClientImpl::write_content_with_provider(Stream &strm, |
nothing calls this directly
no test coverage detected