Switched from curlpp to POCO.

This commit is contained in:
tastytea 2019-08-09 22:38:28 +02:00
parent eee64c1f2d
commit 7b0920ee95
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
9 changed files with 171 additions and 66 deletions

View File

@ -42,8 +42,8 @@ else()
endif()
find_package(jsoncpp CONFIG REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(curlpp REQUIRED IMPORTED_TARGET curlpp)
# Some distributions do not contain Poco*Config.cmake recipes.
find_package(Poco COMPONENTS Foundation Net NetSSL CONFIG)
add_subdirectory(src)

View File

@ -15,7 +15,7 @@ See https://schlomp.space/tastytea/gitea2rss/src/branch/master/gitea2rss.1.adoc[
Add my https://schlomp.space/tastytea/overlay[repository] and install it from
there.
[source,shellsession]
[source,shell]
----
eselect repository enable tastytea
echo "www-misc/gitea2rss ~amd64" >> /etc/portage/package.accept_keywords/gitea2rss
@ -31,21 +31,16 @@ emerge -a dev-util/gitea2rss
* C++ compiler (tested: https://gcc.gnu.org/[gcc] 5/6/7/8,
https://llvm.org/[clang] 3/5/6)
* https://cmake.org/[cmake] (at least: 3.6)
* https://pkgconfig.freedesktop.org/wiki/[pkgconfig] (tested: 0.29)
* http://www.curlpp.org/[curlpp] (tested: 0.8)
* https://pocoproject.org/[POCO] (tested: 1.9 / 1.7)
* https://github.com/open-source-parsers/jsoncpp[jsoncpp] (tested: 1.8)
* Optional:
** Manpage: http://asciidoc.org/[asciidoc] (tested: 8.6)
===== Debian stretch
[source,shellsession]
[source,shell]
----
echo "APT::Default-Release \"stretch\";" >> /etc/apt/apt.conf.d/00default_release
echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
apt-get update
apt-get install build-essential cmake pkg-config libcurl4-openssl-dev libjsoncpp-dev asciidoc
apt-get install -t sid libcurlpp-dev
apt-get install build-essential cmake libpoco-dev libjsoncpp-dev asciidoc
----
==== Get sourcecode
@ -57,14 +52,14 @@ https://schlomp.space/tastytea/gitea2rss/releases[schlomp.space].
===== Development version
[source,shellsession]
[source,shell]
----
git clone https://schlomp.space/tastytea/gitea2rss.git
----
==== Compile
[source,shellsession]
[source,shell]
----
mkdir build
cd build/

View File

@ -2,7 +2,7 @@
:doctype: manpage
:Author: tastytea
:Email: tastytea@tastytea.de
:Date: 2019-04-22
:Date: 2019-08-09
:Revision: 0.0.0
:man source: gitea2rss
:man version: {revision}
@ -57,8 +57,8 @@ this in it:
== PROXY SERVERS
Since gitea2rss is built on libcurl, it respects the same proxy environment
variables. See *curl*(1), section _ENVIRONMENT_.
*gitea2rss* supports HTTP proxies set via the environment variable
_http_proxy_. Accepted formats are _http://host:port/_ or _host:port_.
== EXAMPLES
@ -96,7 +96,7 @@ https://git.example.com/user/project`
== SEE ALSO
*crontab*(1), *crontab*(5), *curl*(1)
*crontab*(1), *crontab*(5)
== REPORTING BUGS

View File

@ -11,6 +11,26 @@ target_include_directories(${PROJECT_NAME}
PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
target_link_libraries(${PROJECT_NAME}
PRIVATE PkgConfig::curlpp jsoncpp_lib)
PRIVATE jsoncpp_lib)
# If no Poco*Config.cmake recipes are found, look for headers in standard dirs.
if(PocoNetSSL_FOUND)
target_link_libraries(${PROJECT_NAME}
PRIVATE Poco::Foundation Poco::Net Poco::NetSSL)
else()
find_file(Poco_h NAMES "Poco/Poco.h"
PATHS "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}")
if("${Poco_h}" STREQUAL "Poco_h-NOTFOUND")
message(FATAL_ERROR "Could not find POCO.")
else()
message(WARNING
"Your distribution of POCO doesn't contain the *Config.cmake recipes, "
"but the files seem to be in the standard directories. "
"Let's hope this works.")
target_link_libraries(${PROJECT_NAME}
PRIVATE PocoFoundation PocoNet PocoNetSSL)
endif()
endif()
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})

View File

@ -28,6 +28,9 @@ using std::uint8_t;
extern bool cgi;
//! Set proxy from environment variable `http_proxy`.
void set_proxy();
//! Fetch HTTP document.
const string get_http(const string &url);

View File

@ -17,58 +17,142 @@
#include <sstream>
#include <iostream>
#include <exception>
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <curlpp/Exception.hpp>
#include <curlpp/Infos.hpp>
#include <memory>
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPSClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/StreamCopier.h>
#include <Poco/URI.h>
#include <Poco/Exception.h>
#include <Poco/Environment.h>
#include "version.hpp"
#include "gitea2rss.hpp"
namespace curlopts = curlpp::options;
using std::cout;
using std::cerr;
using std::endl;
using std::ostringstream;
using std::uint16_t;
using std::istream;
using std::unique_ptr;
using std::make_unique;
using Poco::Net::HTTPClientSession;
using Poco::Net::HTTPSClientSession;
using Poco::Net::HTTPRequest;
using Poco::Net::HTTPResponse;
using Poco::Net::HTTPMessage;
using Poco::StreamCopier;
using Poco::Environment;
const string get_http(const string &url)
void set_proxy()
{
string answer;
try
{
ostringstream oss;
curlpp::Easy request;
HTTPClientSession::ProxyConfig proxy;
string proxy_env = Environment::get("http_proxy");
size_t pos;
request.setOpt<curlopts::UserAgent>(string("gitea2rss/")
+ global::version);
request.setOpt<curlopts::HttpHeader>({ "Connection: close" });
request.setOpt<curlopts::FollowLocation>(true);
request.setOpt<curlopts::Url>(url);
request.setOpt<curlopts::WriteStream>(&oss);
request.perform();
uint16_t ret = curlpp::infos::ResponseCode::get(request);
if (ret == 200 || ret == 302 || ret == 307
|| ret == 301 || ret == 308)
// Only keep text between // and /.
if ((pos = proxy_env.find("//")) != string::npos)
{
answer = oss.str();
proxy_env = proxy_env.substr(pos + 2);
}
if ((pos = proxy_env.find('/')) != string::npos)
{
proxy_env = proxy_env.substr(0, pos);
}
if ((pos = proxy_env.find(':')) != string::npos)
{
proxy.host = proxy_env.substr(0, pos);
proxy.port = std::stoi(proxy_env.substr(pos + 1));
}
else
{
proxy.host = proxy_env;
}
HTTPClientSession::setGlobalProxyConfig(proxy);
}
catch (const std::exception &)
{
// No proxy found, no problem.
}
}
const string get_http(const string &url)
{
try
{
Poco::URI poco_uri(url);
string path = poco_uri.getPathAndQuery();
if (path.empty())
{
path = "/";
}
unique_ptr<HTTPClientSession> session;
if (poco_uri.getScheme() == "https")
{
session = make_unique<HTTPSClientSession>(poco_uri.getHost(),
poco_uri.getPort());
}
else if (poco_uri.getScheme() == "http")
{
session = make_unique<HTTPClientSession>(poco_uri.getHost(),
poco_uri.getPort());
}
else
{
throw Poco::Exception("Protocol not supported.");
}
HTTPRequest request(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
request.set("User-Agent", string("gitea2rss/") + global::version);
HTTPResponse response;
session->sendRequest(request);
istream &rs = session->receiveResponse(response);
// Not using the constants because some are too new for Debian stretch.
switch (response.getStatus())
{
case 301: // HTTPResponse::HTTP_MOVED_PERMANENTLY
case 308: // HTTPResponse::HTTP_PERMANENT_REDIRECT
case 302: // HTTPResponse::HTTP_FOUND
case 303: // HTTPResponse::HTTP_SEE_OTHER
case 307: // HTTPResponse::HTTP_TEMPORARY_REDIRECT
{
string location = response.get("Location");
if (location.substr(0, 4) != "http")
{
location = poco_uri.getScheme() + "://" + poco_uri.getHost()
+ location;
}
return get_http(location);
}
case HTTPResponse::HTTP_OK:
{
string answer;
StreamCopier::copyToString(rs, answer);
return answer;
}
default:
{
if (cgi)
{
cout << "Status: " << std::to_string(ret) << endl;
cout << "Status: " << response.getStatus() << endl;
}
cerr << "HTTP Error: " << std::to_string(ret) << endl;
cerr << "HTTP Error: " << response.getStatus() << endl;
return "";
}
}
}
catch (const std::exception &e)
catch (const Poco::Exception &e)
{
cerr << "Error: " << e.what() << endl;
cerr << "Error: " << e.displayText() << endl;
}
return answer;
return "";
}

View File

@ -16,8 +16,8 @@
#include <iostream>
#include <string>
#include <cstdlib>
#include <curlpp/cURLpp.hpp>
#include <Poco/Net/NetSSL.h>
#include <Poco/Environment.h>
#include "version.hpp"
#include "gitea2rss.hpp"
@ -26,20 +26,22 @@ using std::cerr;
using std::endl;
using std::string;
using std::chrono::system_clock;
using Poco::Environment;
int main(int argc, char *argv[])
{
const char *envquery = std::getenv("QUERY_STRING");
const string query = Environment::get("QUERY_STRING");
string url;
string type = "releases";
curlpp::initialize();
Poco::Net::initializeSSL();
if (envquery != nullptr)
set_proxy();
if (!query.empty())
{
const string query = envquery;
const char *envbaseurl = std::getenv("GITEA2RSS_BASEURL");
if (envbaseurl == nullptr)
const string baseurl = Environment::get("GITEA2RSS_BASEURL");
if (baseurl.empty())
{
cout << "Status: 500 Internal Server Error\n\n";
cerr << "Error: GITEA2RSS_BASEURL not set\n";
@ -56,7 +58,7 @@ int main(int argc, char *argv[])
}
const size_t pos_repo = pos_found + 5;
const size_t pos_endrepo = query.find('&', pos_repo) - pos_repo;
url = string(envbaseurl) + "/" + query.substr(pos_repo, pos_endrepo);
url = string(baseurl) + "/" + query.substr(pos_repo, pos_endrepo);
// Look for type in QUERY_STRING.
pos_found = query.find("type=");
@ -101,7 +103,7 @@ int main(int argc, char *argv[])
cout << " </channel>\n"
"</rss>\n";
curlpp::terminate();
Poco::Net::uninitializeSSL();
return 0;
}

View File

@ -16,11 +16,12 @@
#include <iostream>
#include <regex>
#include <cstdlib>
#include <Poco/Environment.h>
#include "version.hpp"
#include "gitea2rss.hpp"
using std::cout;
using Poco::Environment;
void write_line(const uint8_t spaces, const string &tag, const string &value)
{
@ -43,14 +44,14 @@ void write_line(const uint8_t spaces, const string &tag, const string &value)
void write_preamble(const string &url, const string &type)
{
const char *request_uri = std::getenv("REQUEST_URI");
const char *server_name = std::getenv("SERVER_NAME");
const char *https = getenv("HTTPS");
const string request_uri = Environment::get("REQUEST_URI");
const string server_name = Environment::get("SERVER_NAME");
const string https = Environment::get("HTTPS");
string selfurl;
if (request_uri != nullptr && server_name != nullptr)
if (!request_uri.empty() && !server_name.empty())
{
if (https != nullptr && string(https) == "on")
if (https == "on")
{
selfurl = "https://";
}

View File

@ -9,7 +9,7 @@ target_include_directories(${PROJECT_NAME}_testlib
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/src>")
target_link_libraries(${PROJECT_NAME}_testlib
PRIVATE PkgConfig::curlpp jsoncpp_lib)
PRIVATE Poco::Foundation Poco::Net Poco::NetSSL jsoncpp_lib)
file(GLOB sources_tests test_*.cpp)