diff --git a/include/tgbot/net/CurlHttpClient.h b/include/tgbot/net/CurlHttpClient.h index 0089ddbe..393e3436 100644 --- a/include/tgbot/net/CurlHttpClient.h +++ b/include/tgbot/net/CurlHttpClient.h @@ -47,8 +47,19 @@ class TGBOT_API CurlHttpClient : public HttpClient { */ std::mutex curlHandlesMutex; + /** + * @brief Proxy URL (NULL = no proxy). + */ + void setProxy(const char* url = NULL, long timeout = 20L) { + _proxyUrl = url; + _connectTimeout = timeout; + } + private: const HttpParser _httpParser; + const char* _proxyUrl = NULL; + long _connectTimeout = 20L; + }; } diff --git a/samples/echobot-curl-proxy-carousel/CMakeLists.txt b/samples/echobot-curl-proxy-carousel/CMakeLists.txt new file mode 100644 index 00000000..bf778c6c --- /dev/null +++ b/samples/echobot-curl-proxy-carousel/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.10.2) +project(echobot-curl-proxy-carousel) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") +set(Boost_USE_MULTITHREADED ON) + +find_package(Threads REQUIRED) +find_package(OpenSSL REQUIRED) +find_package(Boost COMPONENTS system REQUIRED) +find_package(CURL) +include_directories(/usr/local/include ${OPENSSL_INCLUDE_DIR} ${Boost_INCLUDE_DIR}) +if (CURL_FOUND) + include_directories(${CURL_INCLUDE_DIRS}) + add_definitions(-DHAVE_CURL) +endif() + +add_executable(echobot-curl-proxy-carousel src/main.cpp) + +target_link_libraries(echobot-curl-proxy-carousel /usr/local/lib/libTgBot.a ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES} ${Boost_LIBRARIES} ${CURL_LIBRARIES}) diff --git a/samples/echobot-curl-proxy-carousel/Dockerfile b/samples/echobot-curl-proxy-carousel/Dockerfile new file mode 100644 index 00000000..352c467a --- /dev/null +++ b/samples/echobot-curl-proxy-carousel/Dockerfile @@ -0,0 +1,8 @@ +FROM reo7sp/tgbot-cpp +MAINTAINER Oleg Morozenkov + +WORKDIR /usr/src/echobot-curl-proxy-carousel +COPY . . +RUN cmake . +RUN make -j4 +CMD ./echobot-curl-proxy-carousel diff --git a/samples/echobot-curl-proxy-carousel/src/main.cpp b/samples/echobot-curl-proxy-carousel/src/main.cpp new file mode 100644 index 00000000..eff10c94 --- /dev/null +++ b/samples/echobot-curl-proxy-carousel/src/main.cpp @@ -0,0 +1,83 @@ +// Example of using array of proxies wth tgbot-cpp library. +// Based on original code (c) Oleg Morozenkov [reo7sp] https://github.com/reo7sp +// https://github.com/reo7sp/tgbot-cpp/blob/master/samples/echobot-curl-client/src/main.cpp + +#include +#include +#include +#include +#include +#include + +#ifndef HAVE_CURL +#define HAVE_CURL +#endif + +#include +#include + +using namespace std; +using namespace TgBot; + +#define CONNECT_TIMEOUT 10L + +int main() { + // Filling array of proxies. + vector proxies; + // NULL = no proxy, direct connection to API. + proxies.push_back(NULL); // [0] + // All proxy-URLs below are fake. Use yuor own. + proxies.push_back("socks5://user:password@10.20.30.40:1080"); // [1] + proxies.push_back("http://user:password@192.168.50.70:3128"); // [2] + proxies.push_back("http://user:password@192.168.80.90:3128"); // [3] + // Choose "staring" index of proxy. In this example [0] - NULL=no proxy. + size_t proxy_now = 0; + + string token(getenv("TOKEN")); + printf("Token: %s\n", token.c_str()); + + CurlHttpClient curlHttpClient; + Bot bot(token, curlHttpClient); + + bot.getEvents().onCommand("start", [&bot](Message::Ptr message) { + bot.getApi().sendMessage(message->chat->id, "Hi!"); + }); + bot.getEvents().onAnyMessage([&bot](Message::Ptr message) { + printf("User wrote %s\n", message->text.c_str()); + if (StringTools::startsWith(message->text, "/start")) return; + bot.getApi().sendMessage(message->chat->id, + "Your message is: " + message->text); + }); + + signal(SIGINT, [](int s) { + printf("SIGINT got: %i\n", s); + exit(0); + }); + + while (true) { + try { + printf("Bot username: %s\n", bot.getApi().getMe()->username.c_str()); + bot.getApi().deleteWebhook(); + + TgLongPoll longPoll(bot); + while (true) { + printf("Long poll started\n"); + longPoll.start(); + } + } catch (exception &e) { + printf("Proxy[%li]: %s error\n", proxy_now, proxies[proxy_now]); + printf("%s\n", e.what()); + // Assumption: + // the reason of exception was - disconnect, + // connection timeout or other network problem. + // Trying to switch (cycle) to next proxy in array. + proxy_now++; + if (proxy_now >= proxies.size()) proxy_now = 0; + curlHttpClient.setProxy(proxies[proxy_now], CONNECT_TIMEOUT); + printf("Switch proxy[%li]: %s\n", proxy_now, proxies[proxy_now]); + } + } + return 0; +} + +// eof diff --git a/src/net/CurlHttpClient.cpp b/src/net/CurlHttpClient.cpp index fe6a7387..39f3956b 100644 --- a/src/net/CurlHttpClient.cpp +++ b/src/net/CurlHttpClient.cpp @@ -44,8 +44,10 @@ std::string CurlHttpClient::makeRequest(const Url& url, const std::vector