diff options
-rw-r--r-- | src/uaLookup.cpp | 47 | ||||
-rw-r--r-- | src/uaLookup.hpp | 20 | ||||
-rw-r--r-- | test/test-ingest.cpp | 16 |
3 files changed, 52 insertions, 31 deletions
diff --git a/src/uaLookup.cpp b/src/uaLookup.cpp index d62c313..5b31065 100644 --- a/src/uaLookup.cpp +++ b/src/uaLookup.cpp @@ -1,5 +1,4 @@ #include "uaLookup.hpp" -#include "util.hpp" #include <memory> #include <string_view> @@ -11,40 +10,42 @@ namespace WebStat { result->append(ptr, nmemb * size); return nmemb * size; } - - void - addForm(curl_mime * mime, const char * name, const std::string_view data) - { - auto part = curl_mime_addpart(mime); - curl_mime_data(part, data.data(), data.length()); - curl_mime_name(part, name); - }; } - std::string - getUserAgentDetail(const std::string_view uas, const char * baseUrl) + CurlOperation::CurlOperation() : hnd {curl_easy_init()}, err {} { - std::string result; - std::array<char, CURL_ERROR_SIZE> err {}; - std::unique_ptr<CURL, DeleteWith<&curl_easy_cleanup>> hnd {curl_easy_init()}; - curl_easy_setopt(hnd.get(), CURLOPT_URL, baseUrl); curl_easy_setopt(hnd.get(), CURLOPT_NOPROGRESS, 1L); - curl_easy_setopt(hnd.get(), CURLOPT_USERAGENT, "WebStat/0; +https://git.randomdan.homeip.net/repo/webstat/"); curl_easy_setopt(hnd.get(), CURLOPT_MAXREDIRS, 50L); curl_easy_setopt(hnd.get(), CURLOPT_TCP_KEEPALIVE, 1L); curl_easy_setopt(hnd.get(), CURLOPT_FAILONERROR, 1L); curl_easy_setopt(hnd.get(), CURLOPT_ERRORBUFFER, err.data()); curl_easy_setopt(hnd.get(), CURLOPT_WRITEDATA, &result); curl_easy_setopt(hnd.get(), CURLOPT_WRITEFUNCTION, &stringAppend); - std::unique_ptr<curl_mime, DeleteWith<&curl_mime_free>> mime {curl_mime_init(hnd.get())}; - addForm(mime.get(), "uas", uas); - addForm(mime.get(), "getJSON", "all"); - curl_easy_setopt(hnd.get(), CURLOPT_MIMEPOST, mime.get()); + } - if (CURLcode ret = curl_easy_perform(hnd.get()); ret != CURLE_OK) { - throw CurlError {ret, err.data()}; + void + CurlOperation::addForm(const char * name, const std::string_view data) + { + if (!mime) { + mime.reset(curl_mime_init(hnd.get())); + curl_easy_setopt(hnd.get(), CURLOPT_MIMEPOST, mime.get()); } + auto part = curl_mime_addpart(mime.get()); + curl_mime_data(part, data.data(), data.length()); + curl_mime_name(part, name); + } + + std::unique_ptr<CurlOperation> + curlGetUserAgentDetail(const std::string_view uas, const char * baseUrl) + { + auto request = std::make_unique<CurlOperation>(); + + curl_easy_setopt(request->hnd.get(), CURLOPT_URL, baseUrl); + curl_easy_setopt( + request->hnd.get(), CURLOPT_USERAGENT, "WebStat/0; +https://git.randomdan.homeip.net/repo/webstat/"); + request->addForm("uas", uas); + request->addForm("getJSON", "all"); - return result; + return request; } } diff --git a/src/uaLookup.hpp b/src/uaLookup.hpp index 5492f05..843283e 100644 --- a/src/uaLookup.hpp +++ b/src/uaLookup.hpp @@ -1,6 +1,8 @@ #pragma once +#include "util.hpp" #include <curl/curl.h> +#include <memory> #include <stdexcept> #include <string> @@ -12,5 +14,21 @@ namespace WebStat { CURLcode code; }; - std::string getUserAgentDetail(std::string_view uas, const char * baseUrl = "https://useragentstring.com"); + using CurlPtr = std::unique_ptr<CURL, DeleteWith<&curl_easy_cleanup>>; + using CurlMimePtr = std::unique_ptr<curl_mime, DeleteWith<&curl_mime_free>>; + using CurlErrorBuf = std::array<char, CURL_ERROR_SIZE>; + + class CurlOperation { + public: + CurlOperation(); + void addForm(const char * name, std::string_view data); + + CurlPtr hnd; + CurlMimePtr mime; + CurlErrorBuf err; + std::string result; + }; + + std::unique_ptr<CurlOperation> curlGetUserAgentDetail( + std::string_view uas, const char * baseUrl = "https://useragentstring.com"); } diff --git a/test/test-ingest.cpp b/test/test-ingest.cpp index 1a62b70..7889a4c 100644 --- a/test/test-ingest.cpp +++ b/test/test-ingest.cpp @@ -185,13 +185,15 @@ BOOST_DATA_TEST_CASE(StoreLogLine, BOOST_AUTO_TEST_CASE(FetchRealUserAgentDetail, *boost::unit_test::disabled()) { - const auto uaDetail = WebStat::getUserAgentDetail( + const auto uaDetailReq = WebStat::curlGetUserAgentDetail( R"(Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36)"); - - BOOST_TEST_CONTEXT(uaDetail) { - BOOST_CHECK(uaDetail.starts_with("{")); - BOOST_CHECK(uaDetail.ends_with("}")); - BOOST_CHECK(uaDetail.contains(R"("agent_type":)")); - BOOST_CHECK(uaDetail.contains(R"("os_type":)")); + BOOST_REQUIRE(uaDetailReq); + BOOST_REQUIRE_EQUAL(CURLE_OK, curl_easy_perform(uaDetailReq->hnd.get())); + + BOOST_TEST_CONTEXT(uaDetailReq->result) { + BOOST_CHECK(uaDetailReq->result.starts_with("{")); + BOOST_CHECK(uaDetailReq->result.ends_with("}")); + BOOST_CHECK(uaDetailReq->result.contains(R"("agent_type":)")); + BOOST_CHECK(uaDetailReq->result.contains(R"("os_type":)")); } } |