diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2a5991a..c67f404 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,23 +4,10 @@ include(GNUInstallDirs) find_package(Boost 1.62 REQUIRED COMPONENTS filesystem log regex) find_package(PkgConfig REQUIRED) pkg_check_modules(jsoncpp REQUIRED IMPORTED_TARGET jsoncpp) -find_package(CURL 7.52 REQUIRED) find_package(Threads REQUIRED) -find_package(restclient-cpp 0.5 CONFIG) find_package(mastodonpp 0.5.6 REQUIRED CONFIG) -if(NOT ${restclient-cpp_FOUND}) - find_file(restclient_h NAMES "restclient-cpp/restclient.h" - PATHS "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}") - if("${restclient_h}" STREQUAL "restclient_h-NOTFOUND") - message(FATAL_ERROR "Could not find restclient-cpp.") - else() - message(WARNING - "Your distribution of restclient-cpp doesn't contain the *Config.cmake " - "recipes, but the files seem to be in the standard directories. " - "Let's hope this works.") - endif() -endif() +add_subdirectory(curl_wrapper) # Write version in header. configure_file ("${PROJECT_SOURCE_DIR}/src/version.hpp.in" @@ -32,7 +19,7 @@ file(GLOB sources *.cpp) add_executable(mastorss ${sources}) target_link_libraries(mastorss PRIVATE - PkgConfig::jsoncpp restclient-cpp mastodonpp::mastodonpp + PkgConfig::jsoncpp curl_wrapper mastodonpp::mastodonpp Boost::filesystem Boost::log Boost::regex) if(BUILD_SHARED_LIBS) target_compile_definitions(mastorss PRIVATE "BOOST_ALL_DYN_LINK=1") diff --git a/src/document.cpp b/src/document.cpp index e8f5e6a..60ddb41 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -16,6 +16,7 @@ #include "document.hpp" +#include "curl_wrapper.hpp" #include "exceptions.hpp" #include "version.hpp" @@ -24,7 +25,6 @@ #include #include #include -#include #include #include @@ -54,39 +54,29 @@ Document::Document(Config &cfg) : _cfg{cfg} , _profiledata{_cfg.profiledata} { - RestClient::init(); - BOOST_LOG_TRIVIAL(debug) << "Initialized RestClient."; - download(); } -Document::~Document() -{ - RestClient::disable(); -} - void Document::download(const string &uri, const bool temp_redirect) { + namespace cw = curl_wrapper; + BOOST_LOG_TRIVIAL(debug) << "Downloading <" << uri << "> …"; - RestClient::Connection connection{uri}; - connection.SetUserAgent(string("mastorss/").append(version)); - connection.FollowRedirects(false); + cw::CURLWrapper curl; + curl.set_useragent(string("mastorss/") += version); + curl.set_maxredirs(0); - RestClient::Response response{connection.get("")}; + const auto answer{curl.make_http_request(cw::http_method::GET, uri)}; - BOOST_LOG_TRIVIAL(debug) << "Got response: " << response.code; + BOOST_LOG_TRIVIAL(debug) << "Got response: " << answer.status; BOOST_LOG_TRIVIAL(debug) << "Got Headers:"; - for (const auto &header : response.headers) - { - BOOST_LOG_TRIVIAL(debug) - << " " << header.first << ": " << header.second; - } + BOOST_LOG_TRIVIAL(debug) << answer.headers; - switch (response.code) + switch (answer.status) { case 200: { - _raw_doc = response.body; + _raw_doc = answer.body; BOOST_LOG_TRIVIAL(debug) << "Downloaded feed: " << _profiledata.feedurl; break; } @@ -97,10 +87,10 @@ void Document::download(const string &uri, const bool temp_redirect) { goto temporary_redirect; // NOLINT(cppcoreguidelines-avoid-goto) } - _profiledata.feedurl = extract_location(response.headers); + _profiledata.feedurl = extract_location(answer); if (_profiledata.feedurl.empty()) { - throw HTTPException{response.code}; + throw HTTPException{answer.status}; } // clang-format off @@ -116,10 +106,10 @@ void Document::download(const string &uri, const bool temp_redirect) case 307: { temporary_redirect: - const string newuri{extract_location(response.headers)}; + const string newuri{extract_location(answer)}; if (newuri.empty()) { - throw HTTPException{response.code}; + throw HTTPException{answer.status}; } // clang-format off @@ -129,13 +119,9 @@ temporary_redirect: download(newuri, true); break; } - case -1: - { - throw CURLException{errno}; - } default: { - throw HTTPException{response.code}; + throw HTTPException{answer.status}; } } } @@ -274,23 +260,13 @@ string Document::remove_html(string html) const return html; } -string Document::extract_location(const RestClient::HeaderFields &headers) const +string Document::extract_location(const curl_wrapper::answer &answer) { - string location; - try + const string location = answer.get_header("Location"); + + if (location.empty()) { - location = headers.at("Location"); - } - catch (const std::out_of_range &) - { - try - { - location = headers.at("location"); - } - catch (const std::out_of_range &) - { - throw std::runtime_error{"Could not extract new feed location."}; - } + throw std::runtime_error{"Could not extract new feed location."}; } return location; diff --git a/src/document.hpp b/src/document.hpp index 608dbcc..b219949 100644 --- a/src/document.hpp +++ b/src/document.hpp @@ -1,5 +1,5 @@ /* This file is part of mastorss. - * Copyright © 2019 tastytea + * Copyright © 2019, 2020 tastytea * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,18 +18,18 @@ #define MASTORSS_DOCUMENT_HPP #include "config.hpp" +#include "curl_wrapper.hpp" #include -#include -#include #include +#include namespace mastorss { namespace pt = boost::property_tree; -using std::string; using std::list; +using std::string; /*! * @brief An Item of a feed. @@ -43,7 +43,7 @@ struct Item string link; string title; - friend bool operator !=(const Item &a, const Item &b); + friend bool operator!=(const Item &a, const Item &b); }; /*! @@ -55,7 +55,6 @@ class Document { public: explicit Document(Config &cfg); - ~Document(); Document(const Document &other) = default; Document &operator=(const Document &other) = delete; Document(Document &&other) = default; @@ -83,15 +82,14 @@ private: * * @since 0.10.0 */ - void download(const string &uri, const bool temp_redirect = false); + void download(const string &uri, bool temp_redirect = false); void parse_rss(const pt::ptree &tree); - [[nodiscard]] - string remove_html(string html) const; - [[nodiscard]] - string extract_location(const RestClient::HeaderFields &headers) const; + [[nodiscard]] string remove_html(string html) const; + [[nodiscard]] static string + extract_location(const curl_wrapper::answer &answer); string add_hashtags(const string &text); void parse_watchwords(); }; } // namespace mastorss -#endif // MASTORSS_DOCUMENT_HPP +#endif // MASTORSS_DOCUMENT_HPP