Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Commit

Permalink
Send user agents with all our tools
Browse files Browse the repository at this point in the history
Signed-off-by: Laurent Bonnans <[email protected]>
  • Loading branch information
lbonn committed Aug 9, 2019
1 parent fce6da4 commit ffc53f1
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 42 deletions.
16 changes: 2 additions & 14 deletions src/libaktualizr/http/httpclient.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,6 @@
#include <assert.h>
#include <sstream>

#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/opensslv.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/ssl.h>

#include "crypto/openssl_compat.h"
#include "utilities/aktualizr_version.h"
#include "utilities/utils.h"

Expand Down Expand Up @@ -46,8 +35,7 @@ static size_t writeString(void* contents, size_t size, size_t nmemb, void* userp
return size * nmemb;
}

HttpClient::HttpClient(const std::vector<std::string>* extra_headers)
: user_agent(std::string("Aktualizr/") + aktualizr_version()) {
HttpClient::HttpClient(const std::vector<std::string>* extra_headers) {
curl = curl_easy_init();
if (curl == nullptr) {
throw std::runtime_error("Could not initialize curl");
Expand All @@ -73,7 +61,7 @@ HttpClient::HttpClient(const std::vector<std::string>* extra_headers)
}
}
curlEasySetoptWrapper(curl, CURLOPT_HTTPHEADER, headers);
curlEasySetoptWrapper(curl, CURLOPT_USERAGENT, user_agent.c_str());
curlEasySetoptWrapper(curl, CURLOPT_USERAGENT, Utils::getUserAgent());
}

HttpClient::HttpClient(const HttpClient& curl_in) : pkcs11_key(curl_in.pkcs11_key), pkcs11_cert(curl_in.pkcs11_key) {
Expand Down
1 change: 0 additions & 1 deletion src/libaktualizr/http/httpclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ class HttpClient : public HttpInterface {
CURL *curl;
curl_slist *headers;
HttpResponse perform(CURL *curl_handler, int retry_times, int64_t size_limit);
std::string user_agent;

static CURLcode sslCtxFunction(CURL *handle, void *sslctx, void *parm);
std::unique_ptr<TemporaryFile> tls_ca_file;
Expand Down
19 changes: 19 additions & 0 deletions src/libaktualizr/http/httpclient_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,25 @@ TEST(PostTest, put_performed) {
EXPECT_EQ(json["data"]["key"].asString(), "val");
}

TEST(HttpClient, user_agent) {
{
HttpClient http;

const auto resp = http.get(server + "/user_agent", HttpInterface::kNoLimit);
const auto app = resp.body.substr(0, resp.body.find('/'));
EXPECT_EQ(app, "Aktualizr");
}

Utils::setUserAgent("blah");

{
HttpClient http;

auto resp = http.get(server + "/user_agent", HttpInterface::kNoLimit);
EXPECT_EQ(resp.body, "blah");
}
}

// TODO: add tests for HttpClient::download

#ifndef __NO_MAIN__
Expand Down
26 changes: 26 additions & 0 deletions src/libaktualizr/utilities/utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>

#include "aktualizr_version.h"
#include "logging/logging.h"

const char *adverbs[] = {
Expand Down Expand Up @@ -765,6 +766,17 @@ void Utils::setStorageRootPath(const std::string &storage_root_path) { storage_r

boost::filesystem::path Utils::getStorageRootPath() { return storage_root_path_; }

void Utils::setUserAgent(std::string user_agent) { user_agent_ = std::move(user_agent); }

const char *Utils::getUserAgent() {
if (user_agent_.empty()) {
user_agent_ = (std::string("Aktualizr/") + aktualizr_version());
}
return user_agent_.c_str();
}

std::string Utils::user_agent_;

TemporaryFile::TemporaryFile(const std::string &hint)
: tmp_name_(SafeTempRoot::Get() / boost::filesystem::unique_path(std::string("%%%%-%%%%-").append(hint))) {}

Expand Down Expand Up @@ -857,3 +869,17 @@ int Socket::bind(in_port_t port, bool reuse) {
int Socket::connect() {
return ::connect(socket_fd_, reinterpret_cast<const struct sockaddr *>(&sock_address_), sizeof(sock_address_));
}

CurlEasyWrapper::CurlEasyWrapper() {
handle = curl_easy_init();
if (handle == nullptr) {
throw std::runtime_error("Could not initialize curl handle");
}
curlEasySetoptWrapper(handle, CURLOPT_USERAGENT, Utils::getUserAgent());
}

CurlEasyWrapper::~CurlEasyWrapper() {
if (handle != nullptr) {
curl_easy_cleanup(handle);
}
}
17 changes: 6 additions & 11 deletions src/libaktualizr/utilities/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,12 @@ struct Utils {
static void setStorageRootPath(const std::string &storage_root_path);
static boost::filesystem::path getStorageRootPath();

static void setUserAgent(std::string user_agent);
static const char *getUserAgent();

private:
static std::string storage_root_path_;
static std::string user_agent_;
};

/**
Expand Down Expand Up @@ -144,17 +148,8 @@ class Socket {
// wrapper for curl handles
class CurlEasyWrapper {
public:
CurlEasyWrapper() {
handle = curl_easy_init();
if (handle == nullptr) {
throw std::runtime_error("Could not initialize curl handle");
}
}
~CurlEasyWrapper() {
if (handle != nullptr) {
curl_easy_cleanup(handle);
}
}
CurlEasyWrapper();
~CurlEasyWrapper();
CURL *get() { return handle; }

private:
Expand Down
8 changes: 4 additions & 4 deletions src/libaktualizr/utilities/utils_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ TEST(Utils, TemporaryDirectory) {
EXPECT_TRUE(boost::filesystem::exists(p)); // The dir should exist
EXPECT_NE(p.string().find("ahint"), std::string::npos); // The hint is included in the filename

struct stat statbuf;
struct stat statbuf {};
EXPECT_GE(stat(p.parent_path().c_str(), &statbuf), 0);
EXPECT_EQ(statbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO), S_IRWXU);
}
Expand All @@ -203,7 +203,7 @@ TEST(Utils, TemporaryFile) {
EXPECT_TRUE(boost::filesystem::exists(p)); // The file should exist here
EXPECT_NE(p.string().find("ahint"), std::string::npos); // The hint is included in the filename

struct stat statbuf;
struct stat statbuf {};
EXPECT_GE(stat(p.parent_path().c_str(), &statbuf), 0);
EXPECT_EQ(statbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO), S_IRWXU);
}
Expand Down Expand Up @@ -298,7 +298,7 @@ TEST(Utils, ipUtils) {
EXPECT_NE(fd, -1);
SocketHandle hdl(new int(fd));

sockaddr_in6 sa;
sockaddr_in6 sa{};

memset(&sa, 0, sizeof(sa));
sa.sin6_family = AF_INET6;
Expand All @@ -312,7 +312,7 @@ TEST(Utils, ipUtils) {

EXPECT_NE(bind(*hdl, reinterpret_cast<const sockaddr *>(&sa), sizeof(sa)), -1);

sockaddr_storage ss;
sockaddr_storage ss{};
EXPECT_NO_THROW(ss = Utils::ipGetSockaddr(*hdl));

EXPECT_NE(Utils::ipDisplayName(ss), "unknown");
Expand Down
2 changes: 2 additions & 0 deletions src/sota_tools/garage_check.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ int main(int argc, char **argv) {
assert(0);
}

Utils::setUserAgent(std::string("garage-check/") + garage_tools_version());

if (vm.count("walk-tree") != 0u) {
mode = RunMode::kWalkTree;
}
Expand Down
2 changes: 2 additions & 0 deletions src/sota_tools/garage_deploy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ int main(int argc, char **argv) {
assert(0);
}

Utils::setUserAgent(std::string("garage-deploy/") + garage_tools_version());

if (vm.count("dry-run") != 0u) {
mode = RunMode::kDryRun;
}
Expand Down
2 changes: 2 additions & 0 deletions src/sota_tools/garage_push.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ int main(int argc, char **argv) {
assert(0);
}

Utils::setUserAgent(std::string("garage-push/") + garage_tools_version());

if (cacerts != "") {
if (!boost::filesystem::exists(cacerts)) {
LOG_FATAL << "--cacert path " << cacerts << " does not exist";
Expand Down
3 changes: 3 additions & 0 deletions src/sota_tools/ostree_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "logging/logging.h"
#include "ostree_repo.h"
#include "request_pool.h"
#include "utilities/utils.h"

using std::string;

Expand Down Expand Up @@ -191,6 +192,7 @@ void OSTreeObject::MakeTestRequest(const TreehubServer &push_target, CURLM *curl
push_target.InjectIntoCurl(Url(), curl_handle_);
curlEasySetoptWrapper(curl_handle_, CURLOPT_NOBODY, 1L); // HEAD

curlEasySetoptWrapper(curl_handle_, CURLOPT_USERAGENT, Utils::getUserAgent());
curlEasySetoptWrapper(curl_handle_, CURLOPT_WRITEFUNCTION, &OSTreeObject::curl_handle_write);
curlEasySetoptWrapper(curl_handle_, CURLOPT_WRITEDATA, this);
curlEasySetoptWrapper(curl_handle_, CURLOPT_PRIVATE, this); // Used by ostree_object_from_curl
Expand Down Expand Up @@ -221,6 +223,7 @@ void OSTreeObject::Upload(const TreehubServer &push_target, CURLM *curl_multi_ha
curlEasySetoptWrapper(curl_handle_, CURLOPT_VERBOSE, get_curlopt_verbose());
current_operation_ = CurrentOp::kOstreeObjectUploading;
push_target.InjectIntoCurl(Url(), curl_handle_);
curlEasySetoptWrapper(curl_handle_, CURLOPT_USERAGENT, Utils::getUserAgent());
curlEasySetoptWrapper(curl_handle_, CURLOPT_WRITEFUNCTION, &OSTreeObject::curl_handle_write);
curlEasySetoptWrapper(curl_handle_, CURLOPT_WRITEDATA, this);
http_response_.str(""); // Empty the response buffer
Expand Down
5 changes: 5 additions & 0 deletions tests/fake_http_server/fake_test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ def do_GET(self):
for i in range(5):
self.wfile.write(b'aa')
sleep(1)
elif self.path == '/user_agent':
user_agent = self.headers.get('user-agent')
self.send_response(200)
self.end_headers()
self.wfile.write(user_agent.encode())
else:
if self.server.fail_injector is not None and self.server.fail_injector.fail(self):
return
Expand Down
20 changes: 8 additions & 12 deletions tests/test_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,17 @@ void TestUtils::writePathToConfig(const boost::filesystem::path &toml_in, const
}

void TestUtils::waitForServer(const std::string &address) {
CURL *handle = curl_easy_init();
if (handle == nullptr) {
throw std::runtime_error("Could not initialize curl handle");
}
curlEasySetoptWrapper(handle, CURLOPT_URL, address.c_str());
curlEasySetoptWrapper(handle, CURLOPT_CONNECTTIMEOUT, 3L);
curlEasySetoptWrapper(handle, CURLOPT_NOBODY, 1L);
curlEasySetoptWrapper(handle, CURLOPT_VERBOSE, 1L);
curlEasySetoptWrapper(handle, CURLOPT_SSL_VERIFYPEER, 0L);
CurlEasyWrapper curl;

curlEasySetoptWrapper(curl.get(), CURLOPT_URL, address.c_str());
curlEasySetoptWrapper(curl.get(), CURLOPT_CONNECTTIMEOUT, 3L);
curlEasySetoptWrapper(curl.get(), CURLOPT_NOBODY, 1L);
curlEasySetoptWrapper(curl.get(), CURLOPT_VERBOSE, 1L);
curlEasySetoptWrapper(curl.get(), CURLOPT_SSL_VERIFYPEER, 0L);

CURLcode result;
for (size_t counter = 1; counter <= 100; counter++) {
result = curl_easy_perform(handle);
result = curl_easy_perform(curl.get());
if (result == 0) {
// connection successful
break;
Expand All @@ -78,8 +76,6 @@ void TestUtils::waitForServer(const std::string &address) {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}

curl_easy_cleanup(handle);

if (result != 0) {
throw std::runtime_error("Wait for server timed out");
}
Expand Down

0 comments on commit ffc53f1

Please sign in to comment.