/////////////////////////////////////////////////////// Request a URL ///////////////////////////////////////////////////////
| 15 | /// |
| 16 | //////////////////////////////////////////////////////////// |
| 17 | void requestUrl(const std::string& url, int redirectsRemaining) |
| 18 | { |
| 19 | // Split the URL up into host and resource parts |
| 20 | const auto resourcePos = url.find('/', url.find("://") + 3); |
| 21 | const auto resource = (resourcePos != std::string::npos) ? url.substr(resourcePos) : std::string("/"); |
| 22 | const auto host = url.substr(0, resourcePos); |
| 23 | const auto portPos = host.find(':', 6); |
| 24 | const auto port = (portPos != std::string::npos) ? host.substr(portPos + 1) : std::string("0"); |
| 25 | |
| 26 | // Create a new HTTP client |
| 27 | sf::Http http; |
| 28 | |
| 29 | http.setHost(host.substr(0, portPos), static_cast<unsigned short>(std::stoi(port))); |
| 30 | |
| 31 | // Prepare a request to get the resource |
| 32 | const sf::Http::Request request(resource); |
| 33 | |
| 34 | // Send the request |
| 35 | const sf::Http::Response response = http.sendRequest(request); |
| 36 | |
| 37 | // Check the numeric status code and display the result |
| 38 | const auto statusNum = static_cast<int>(response.getStatus()); |
| 39 | std::cout << "Server responded with HTTP status " << statusNum << '\n' << std::endl; |
| 40 | |
| 41 | // Output body if its content type is text-based and not compressed |
| 42 | if (response.getField("Content-Type").find("text") == 0) |
| 43 | { |
| 44 | if (const auto encoding = response.getField("Content-Encoding"); encoding.empty()) |
| 45 | { |
| 46 | std::cout << response.getBody() << std::endl; |
| 47 | } |
| 48 | else |
| 49 | { |
| 50 | std::cout << encoding << " compressed body content, length: " << response.getBody().size() << '\n' |
| 51 | << std::endl; |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | // Follow redirections (HTTP status codes 301 to 308) |
| 56 | static constexpr auto movedPermanently = 301; |
| 57 | static constexpr auto permanentRedirect = 308; |
| 58 | if (statusNum >= movedPermanently && statusNum <= permanentRedirect) |
| 59 | { |
| 60 | if (redirectsRemaining == 0) |
| 61 | { |
| 62 | std::cout << "Maximum number of redirects reached" << std::endl; |
| 63 | return; |
| 64 | } |
| 65 | |
| 66 | if (auto nextUrl = response.getField("Location"); !nextUrl.empty()) |
| 67 | { |
| 68 | if ((nextUrl.find("http://") != 0) && (nextUrl.find("https://") != 0)) |
| 69 | nextUrl = host + nextUrl; |
| 70 | std::cout << "Following redirect to " << nextUrl << '\n' << std::endl; |
| 71 | requestUrl(nextUrl, redirectsRemaining - 1); |
| 72 | } |
| 73 | } |
| 74 | } |
no test coverage detected