Switched from curlpp to POCO.
This commit is contained in:
parent
eee64c1f2d
commit
7b0920ee95
@ -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)
|
||||
|
||||
|
17
README.adoc
17
README.adoc
@ -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/
|
||||
|
@ -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
|
||||
|
||||
|
@ -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})
|
||||
|
@ -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);
|
||||
|
||||
|
146
src/http.cpp
146
src/http.cpp
@ -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 "";
|
||||
}
|
||||
|
22
src/main.cpp
22
src/main.cpp
@ -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;
|
||||
}
|
||||
|
@ -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://";
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user