|
@@ -3885,10 +3885,10 @@ inline bool Client::redirect(const Request &req, Response &res) {
|
|
|
if (location.empty()) { return false; }
|
|
if (location.empty()) { return false; }
|
|
|
|
|
|
|
|
const static std::regex re(
|
|
const static std::regex re(
|
|
|
- R"(^(?:(https?):)?(?://([^/?#]*)(?:(:\d+))?)?([^?#]*(?:\?[^#]*)?)(?:#.*)?)");
|
|
|
|
|
|
|
+ R"(^(?:(https?):)?(?://([^:/?#]*)(?::(\d+))?)?([^?#]*(?:\?[^#]*)?)(?:#.*)?)");
|
|
|
|
|
|
|
|
std::smatch m;
|
|
std::smatch m;
|
|
|
- if (!regex_match(location, m, re)) { return false; }
|
|
|
|
|
|
|
+ if (!std::regex_match(location, m, re)) { return false; }
|
|
|
|
|
|
|
|
auto scheme = is_ssl() ? "https" : "http";
|
|
auto scheme = is_ssl() ? "https" : "http";
|
|
|
|
|
|
|
@@ -4967,6 +4967,63 @@ inline bool SSLClient::check_host_name(const char *pattern,
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
+namespace url {
|
|
|
|
|
+
|
|
|
|
|
+struct Options {
|
|
|
|
|
+ // TODO: support more options...
|
|
|
|
|
+ bool follow_location = false;
|
|
|
|
|
+ std::string client_cert_path;
|
|
|
|
|
+ std::string client_key_path;
|
|
|
|
|
+
|
|
|
|
|
+ std::string ca_cert_file_path;
|
|
|
|
|
+ std::string ca_cert_dir_path;
|
|
|
|
|
+ bool server_certificate_verification = false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+inline std::shared_ptr<Response> Get(const char *url, Options &options) {
|
|
|
|
|
+ const static std::regex re(
|
|
|
|
|
+ R"(^(https?)://([^:/?#]+)(?::(\d+))?([^?#]*(?:\?[^#]*)?)(?:#.*)?)");
|
|
|
|
|
+
|
|
|
|
|
+ std::cmatch m;
|
|
|
|
|
+ if (!std::regex_match(url, m, re)) { return nullptr; }
|
|
|
|
|
+
|
|
|
|
|
+ auto next_scheme = m[1].str();
|
|
|
|
|
+ auto next_host = m[2].str();
|
|
|
|
|
+ auto port_str = m[3].str();
|
|
|
|
|
+ auto next_path = m[4].str();
|
|
|
|
|
+
|
|
|
|
|
+ auto next_port = !port_str.empty() ? std::stoi(port_str)
|
|
|
|
|
+ : (next_scheme == "https" ? 443 : 80);
|
|
|
|
|
+
|
|
|
|
|
+ if (next_path.empty()) { next_path = "/"; }
|
|
|
|
|
+
|
|
|
|
|
+ if (next_scheme == "https") {
|
|
|
|
|
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
|
|
+ SSLClient cli(next_host.c_str(), next_port, options.client_cert_path,
|
|
|
|
|
+ options.client_key_path);
|
|
|
|
|
+ cli.set_follow_location(options.follow_location);
|
|
|
|
|
+ cli.set_ca_cert_path(options.ca_cert_file_path.c_str(), options.ca_cert_dir_path.c_str());
|
|
|
|
|
+ cli.enable_server_certificate_verification(
|
|
|
|
|
+ options.server_certificate_verification);
|
|
|
|
|
+ return cli.Get(next_path.c_str());
|
|
|
|
|
+#else
|
|
|
|
|
+ return nullptr;
|
|
|
|
|
+#endif
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Client cli(next_host.c_str(), next_port, options.client_cert_path,
|
|
|
|
|
+ options.client_key_path);
|
|
|
|
|
+ cli.set_follow_location(options.follow_location);
|
|
|
|
|
+ return cli.Get(next_path.c_str());
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+inline std::shared_ptr<Response> Get(const char *url) {
|
|
|
|
|
+ Options options;
|
|
|
|
|
+ return Get(url, options);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+} // namespace url
|
|
|
|
|
+
|
|
|
// ----------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
} // namespace httplib
|
|
} // namespace httplib
|