Switched from curlpp to POCO.
This commit is contained in:
parent
eee64c1f2d
commit
7b0920ee95
|
@ -42,8 +42,8 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(jsoncpp CONFIG REQUIRED)
|
find_package(jsoncpp CONFIG REQUIRED)
|
||||||
find_package(PkgConfig REQUIRED)
|
# Some distributions do not contain Poco*Config.cmake recipes.
|
||||||
pkg_check_modules(curlpp REQUIRED IMPORTED_TARGET curlpp)
|
find_package(Poco COMPONENTS Foundation Net NetSSL CONFIG)
|
||||||
|
|
||||||
add_subdirectory(src)
|
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
|
Add my https://schlomp.space/tastytea/overlay[repository] and install it from
|
||||||
there.
|
there.
|
||||||
|
|
||||||
[source,shellsession]
|
[source,shell]
|
||||||
----
|
----
|
||||||
eselect repository enable tastytea
|
eselect repository enable tastytea
|
||||||
echo "www-misc/gitea2rss ~amd64" >> /etc/portage/package.accept_keywords/gitea2rss
|
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,
|
* C++ compiler (tested: https://gcc.gnu.org/[gcc] 5/6/7/8,
|
||||||
https://llvm.org/[clang] 3/5/6)
|
https://llvm.org/[clang] 3/5/6)
|
||||||
* https://cmake.org/[cmake] (at least: 3.6)
|
* https://cmake.org/[cmake] (at least: 3.6)
|
||||||
* https://pkgconfig.freedesktop.org/wiki/[pkgconfig] (tested: 0.29)
|
* https://pocoproject.org/[POCO] (tested: 1.9 / 1.7)
|
||||||
* http://www.curlpp.org/[curlpp] (tested: 0.8)
|
|
||||||
* https://github.com/open-source-parsers/jsoncpp[jsoncpp] (tested: 1.8)
|
* https://github.com/open-source-parsers/jsoncpp[jsoncpp] (tested: 1.8)
|
||||||
* Optional:
|
* Optional:
|
||||||
** Manpage: http://asciidoc.org/[asciidoc] (tested: 8.6)
|
** Manpage: http://asciidoc.org/[asciidoc] (tested: 8.6)
|
||||||
|
|
||||||
===== Debian stretch
|
===== Debian stretch
|
||||||
|
|
||||||
[source,shellsession]
|
[source,shell]
|
||||||
----
|
----
|
||||||
echo "APT::Default-Release \"stretch\";" >> /etc/apt/apt.conf.d/00default_release
|
apt-get install build-essential cmake libpoco-dev libjsoncpp-dev asciidoc
|
||||||
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
|
|
||||||
----
|
----
|
||||||
|
|
||||||
==== Get sourcecode
|
==== Get sourcecode
|
||||||
|
@ -57,14 +52,14 @@ https://schlomp.space/tastytea/gitea2rss/releases[schlomp.space].
|
||||||
|
|
||||||
===== Development version
|
===== Development version
|
||||||
|
|
||||||
[source,shellsession]
|
[source,shell]
|
||||||
----
|
----
|
||||||
git clone https://schlomp.space/tastytea/gitea2rss.git
|
git clone https://schlomp.space/tastytea/gitea2rss.git
|
||||||
----
|
----
|
||||||
|
|
||||||
==== Compile
|
==== Compile
|
||||||
|
|
||||||
[source,shellsession]
|
[source,shell]
|
||||||
----
|
----
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build/
|
cd build/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
:doctype: manpage
|
:doctype: manpage
|
||||||
:Author: tastytea
|
:Author: tastytea
|
||||||
:Email: tastytea@tastytea.de
|
:Email: tastytea@tastytea.de
|
||||||
:Date: 2019-04-22
|
:Date: 2019-08-09
|
||||||
:Revision: 0.0.0
|
:Revision: 0.0.0
|
||||||
:man source: gitea2rss
|
:man source: gitea2rss
|
||||||
:man version: {revision}
|
:man version: {revision}
|
||||||
|
@ -57,8 +57,8 @@ this in it:
|
||||||
|
|
||||||
== PROXY SERVERS
|
== PROXY SERVERS
|
||||||
|
|
||||||
Since gitea2rss is built on libcurl, it respects the same proxy environment
|
*gitea2rss* supports HTTP proxies set via the environment variable
|
||||||
variables. See *curl*(1), section _ENVIRONMENT_.
|
_http_proxy_. Accepted formats are _http://host:port/_ or _host:port_.
|
||||||
|
|
||||||
== EXAMPLES
|
== EXAMPLES
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ https://git.example.com/user/project`
|
||||||
|
|
||||||
== SEE ALSO
|
== SEE ALSO
|
||||||
|
|
||||||
*crontab*(1), *crontab*(5), *curl*(1)
|
*crontab*(1), *crontab*(5)
|
||||||
|
|
||||||
== REPORTING BUGS
|
== REPORTING BUGS
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,26 @@ target_include_directories(${PROJECT_NAME}
|
||||||
PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
|
PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
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})
|
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
|
@ -28,6 +28,9 @@ using std::uint8_t;
|
||||||
|
|
||||||
extern bool cgi;
|
extern bool cgi;
|
||||||
|
|
||||||
|
//! Set proxy from environment variable `http_proxy`.
|
||||||
|
void set_proxy();
|
||||||
|
|
||||||
//! Fetch HTTP document.
|
//! Fetch HTTP document.
|
||||||
const string get_http(const string &url);
|
const string get_http(const string &url);
|
||||||
|
|
||||||
|
|
146
src/http.cpp
146
src/http.cpp
|
@ -17,58 +17,142 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <curlpp/cURLpp.hpp>
|
#include <memory>
|
||||||
#include <curlpp/Easy.hpp>
|
#include <Poco/Net/HTTPClientSession.h>
|
||||||
#include <curlpp/Options.hpp>
|
#include <Poco/Net/HTTPSClientSession.h>
|
||||||
#include <curlpp/Exception.hpp>
|
#include <Poco/Net/HTTPRequest.h>
|
||||||
#include <curlpp/Infos.hpp>
|
#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 "version.hpp"
|
||||||
#include "gitea2rss.hpp"
|
#include "gitea2rss.hpp"
|
||||||
|
|
||||||
namespace curlopts = curlpp::options;
|
|
||||||
|
|
||||||
using std::cout;
|
using std::cout;
|
||||||
using std::cerr;
|
using std::cerr;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
using std::ostringstream;
|
using std::istream;
|
||||||
using std::uint16_t;
|
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
|
try
|
||||||
{
|
{
|
||||||
ostringstream oss;
|
HTTPClientSession::ProxyConfig proxy;
|
||||||
curlpp::Easy request;
|
string proxy_env = Environment::get("http_proxy");
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
request.setOpt<curlopts::UserAgent>(string("gitea2rss/")
|
// Only keep text between // and /.
|
||||||
+ global::version);
|
if ((pos = proxy_env.find("//")) != string::npos)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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
|
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)
|
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 <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdlib>
|
#include <Poco/Net/NetSSL.h>
|
||||||
#include <curlpp/cURLpp.hpp>
|
#include <Poco/Environment.h>
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
#include "gitea2rss.hpp"
|
#include "gitea2rss.hpp"
|
||||||
|
|
||||||
|
@ -26,20 +26,22 @@ using std::cerr;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::chrono::system_clock;
|
using std::chrono::system_clock;
|
||||||
|
using Poco::Environment;
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
const char *envquery = std::getenv("QUERY_STRING");
|
const string query = Environment::get("QUERY_STRING");
|
||||||
string url;
|
string url;
|
||||||
string type = "releases";
|
string type = "releases";
|
||||||
|
|
||||||
curlpp::initialize();
|
Poco::Net::initializeSSL();
|
||||||
|
|
||||||
if (envquery != nullptr)
|
set_proxy();
|
||||||
|
|
||||||
|
if (!query.empty())
|
||||||
{
|
{
|
||||||
const string query = envquery;
|
const string baseurl = Environment::get("GITEA2RSS_BASEURL");
|
||||||
const char *envbaseurl = std::getenv("GITEA2RSS_BASEURL");
|
if (baseurl.empty())
|
||||||
if (envbaseurl == nullptr)
|
|
||||||
{
|
{
|
||||||
cout << "Status: 500 Internal Server Error\n\n";
|
cout << "Status: 500 Internal Server Error\n\n";
|
||||||
cerr << "Error: GITEA2RSS_BASEURL not set\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_repo = pos_found + 5;
|
||||||
const size_t pos_endrepo = query.find('&', pos_repo) - pos_repo;
|
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.
|
// Look for type in QUERY_STRING.
|
||||||
pos_found = query.find("type=");
|
pos_found = query.find("type=");
|
||||||
|
@ -101,7 +103,7 @@ int main(int argc, char *argv[])
|
||||||
cout << " </channel>\n"
|
cout << " </channel>\n"
|
||||||
"</rss>\n";
|
"</rss>\n";
|
||||||
|
|
||||||
curlpp::terminate();
|
Poco::Net::uninitializeSSL();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,12 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <cstdlib>
|
#include <Poco/Environment.h>
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
#include "gitea2rss.hpp"
|
#include "gitea2rss.hpp"
|
||||||
|
|
||||||
using std::cout;
|
using std::cout;
|
||||||
|
using Poco::Environment;
|
||||||
|
|
||||||
void write_line(const uint8_t spaces, const string &tag, const string &value)
|
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)
|
void write_preamble(const string &url, const string &type)
|
||||||
{
|
{
|
||||||
const char *request_uri = std::getenv("REQUEST_URI");
|
const string request_uri = Environment::get("REQUEST_URI");
|
||||||
const char *server_name = std::getenv("SERVER_NAME");
|
const string server_name = Environment::get("SERVER_NAME");
|
||||||
const char *https = getenv("HTTPS");
|
const string https = Environment::get("HTTPS");
|
||||||
string selfurl;
|
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://";
|
selfurl = "https://";
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ target_include_directories(${PROJECT_NAME}_testlib
|
||||||
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/src>")
|
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/src>")
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}_testlib
|
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)
|
file(GLOB sources_tests test_*.cpp)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue