GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/swissknife_lease_curl.cc Lines: 0 66 0.0 %
Date: 2019-02-03 02:48:13 Branches: 0 20 0.0 %

Line Branch Exec Source
1
/**
2
 * This file is part of the CernVM File System.
3
 */
4
5
#include "swissknife_lease_curl.h"
6
7
#include "cvmfs_config.h"
8
9
#include "gateway_util.h"
10
#include "hash.h"
11
#include "logging.h"
12
#include "util/string.h"
13
14
namespace {
15
16
CURL* PrepareCurl(const std::string& method) {
17
  const char* user_agent_string = "cvmfs/" VERSION;
18
19
  CURL* h_curl = curl_easy_init();
20
21
  if (h_curl) {
22
    curl_easy_setopt(h_curl, CURLOPT_NOPROGRESS, 1L);
23
    curl_easy_setopt(h_curl, CURLOPT_USERAGENT, user_agent_string);
24
    curl_easy_setopt(h_curl, CURLOPT_MAXREDIRS, 50L);
25
    curl_easy_setopt(h_curl, CURLOPT_CUSTOMREQUEST, method.c_str());
26
  }
27
28
  return h_curl;
29
}
30
31
size_t RecvCB(void* buffer, size_t size, size_t nmemb, void* userp) {
32
  CurlBuffer* my_buffer = static_cast<CurlBuffer*>(userp);
33
34
  if (size * nmemb < 1) {
35
    return 0;
36
  }
37
38
  my_buffer->data = static_cast<char*>(buffer);
39
40
  return my_buffer->data.size();
41
}
42
43
}  // namespace
44
45
bool MakeAcquireRequest(const std::string& key_id, const std::string& secret,
46
                        const std::string& repo_path,
47
                        const std::string& repo_service_url,
48
                        CurlBuffer* buffer) {
49
  CURLcode ret = static_cast<CURLcode>(0);
50
51
  CURL* h_curl = PrepareCurl("POST");
52
  if (!h_curl) {
53
    return false;
54
  }
55
56
  const std::string payload = "{\"path\" : \"" + repo_path +
57
                              "\", \"api_version\" : \"" +
58
                              StringifyInt(gateway::APIVersion()) + "\"}";
59
60
  shash::Any hmac(shash::kSha1);
61
  shash::HmacString(secret, payload, &hmac);
62
63
  const std::string header_str = std::string("Authorization: ") + key_id + " " +
64
                                 Base64(hmac.ToString(false));
65
  struct curl_slist* auth_header = NULL;
66
  auth_header = curl_slist_append(auth_header, header_str.c_str());
67
  curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);
68
69
  // Make request to acquire lease from repo services
70
  curl_easy_setopt(h_curl, CURLOPT_URL, (repo_service_url + "/leases").c_str());
71
  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
72
                   static_cast<curl_off_t>(payload.length()));
73
  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, payload.c_str());
74
  curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION, RecvCB);
75
  curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, buffer);
76
77
  ret = curl_easy_perform(h_curl);
78
  if (ret) {
79
    LogCvmfs(kLogUploadGateway, kLogStderr,
80
             "Make lease acquire request failed: %d. Reply: %s", ret,
81
             buffer->data.c_str());
82
  }
83
84
  curl_easy_cleanup(h_curl);
85
  h_curl = NULL;
86
87
  return !ret;
88
}
89
90
bool MakeEndRequest(const std::string& method, const std::string& key_id,
91
                    const std::string& secret, const std::string& session_token,
92
                    const std::string& repo_service_url,
93
                    const std::string& request_payload, CurlBuffer* reply) {
94
  CURLcode ret = static_cast<CURLcode>(0);
95
96
  CURL* h_curl = PrepareCurl(method);
97
  if (!h_curl) {
98
    return false;
99
  }
100
101
  shash::Any hmac(shash::kSha1);
102
  shash::HmacString(secret, session_token, &hmac);
103
104
  const std::string header_str = std::string("Authorization: ") + key_id + " " +
105
                                 Base64(hmac.ToString(false));
106
  struct curl_slist* auth_header = NULL;
107
  auth_header = curl_slist_append(auth_header, header_str.c_str());
108
  curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);
109
110
  curl_easy_setopt(h_curl, CURLOPT_URL,
111
                   (repo_service_url + "/leases/" + session_token).c_str());
112
  if (request_payload != "") {
113
    curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
114
                     static_cast<curl_off_t>(request_payload.length()));
115
    curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, request_payload.c_str());
116
  } else {
117
    curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
118
                     static_cast<curl_off_t>(0));
119
    curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, NULL);
120
  }
121
  curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION, RecvCB);
122
  curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, reply);
123
124
  ret = curl_easy_perform(h_curl);
125
  if (ret) {
126
    LogCvmfs(kLogUploadGateway, kLogStderr,
127
             "Lease end request - curl_easy_perform failed: %d", ret);
128
  }
129
130
  const bool ok = (reply->data == "{\"status\":\"ok\"}");
131
  if (!ok) {
132
    LogCvmfs(kLogUploadGateway, kLogStderr,
133
             "Lease end request - error reply: %s",
134
             reply->data.c_str());
135
  }
136
137
  curl_easy_cleanup(h_curl);
138
  h_curl = NULL;
139
140
  return ok && !ret;
141
}