diff --git a/src/document.cpp b/src/document.cpp index b811dcb..15203c3 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -53,11 +52,11 @@ Document::~Document() RestClient::disable(); } -void Document::download() +void Document::download(const string &uri) { - RestClient::Connection connection(_data.feedurl); + RestClient::Connection connection{uri}; connection.SetUserAgent(string("mastorss/").append(version)); - connection.FollowRedirects(true, 10); + connection.FollowRedirects(false); RestClient::Response response{connection.get("")}; @@ -72,9 +71,30 @@ void Document::download() case 301: case 308: { - // TODO(tastytea): Handle permanent redirections. - throw std::runtime_error{"Permanent redirect, " - "no solution implemented yet."}; + _data.feedurl = extract_location(response.headers); + if (_data.feedurl.empty()) + { + throw HTTPException{response.code}; + } + + BOOST_LOG_TRIVIAL(debug) << "Feed has new location: " << _data.feedurl; + _cfg.write(); + download(); + break; + } + case 302: + case 303: + case 307: + { + string newuri{extract_location(response.headers)}; + if (newuri.empty()) + { + throw HTTPException{response.code}; + } + + BOOST_LOG_TRIVIAL(debug) << "Feed redirect: " << _data.feedurl; + download(move(newuri)); + break; } case -1: { @@ -87,6 +107,11 @@ void Document::download() } } +void Document::download() +{ + download(_data.feedurl); +} + void Document::parse() { pt::ptree tree; @@ -185,4 +210,14 @@ string Document::remove_html(string html) const return html; } + +string Document::extract_location(const RestClient::HeaderFields &headers) const +{ + string location{headers.at("Location")}; + if (location.empty()) + { + location = headers.at("location"); + } + return location; +} } // namespace mastorss diff --git a/src/document.hpp b/src/document.hpp index 31b91e4..7a9c422 100644 --- a/src/document.hpp +++ b/src/document.hpp @@ -20,6 +20,7 @@ #include "config.hpp" #include +#include #include #include @@ -61,6 +62,7 @@ public: vector new_items; void download(); + void download(const string &uri); void parse(); private: @@ -71,6 +73,8 @@ private: void parse_rss(const pt::ptree &tree); [[nodiscard]] string remove_html(string html) const; + [[nodiscard]] + string extract_location(const RestClient::HeaderFields &headers) const; }; } // namespace mastorss