5 #include "cvmfs_config.h"
41 const char* user_agent_string =
"cvmfs/" VERSION;
43 CURL* h_curl = curl_easy_init();
46 curl_easy_setopt(h_curl, CURLOPT_NOPROGRESS, 1L);
47 curl_easy_setopt(h_curl, CURLOPT_USERAGENT, user_agent_string);
48 curl_easy_setopt(h_curl, CURLOPT_MAXREDIRS, 50L);
49 curl_easy_setopt(h_curl, CURLOPT_CUSTOMREQUEST, method.c_str());
54 static size_t RecvCB(
void* buffer,
size_t size,
size_t nmemb,
void* userp) {
57 if (size * nmemb < 1) {
61 my_buffer->
data =
static_cast<char*
>(buffer);
63 return my_buffer->
data.size();
68 const std::string& repo_path,
69 const std::string& repo_service_url,
73 CURLcode ret =
static_cast<CURLcode
>(0);
77 const std::string payload =
"{\"path\" : \"" + repo_path +
78 "\", \"api_version\" : \"" +
84 const std::string header_str =
85 std::string(
"Authorization: ") + key.
id() +
" " +
87 struct curl_slist* auth_header = NULL;
88 auth_header = curl_slist_append(auth_header, header_str.c_str());
89 curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);
92 curl_easy_setopt(h_curl, CURLOPT_URL, (repo_service_url +
"/leases").c_str());
93 curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
94 static_cast<curl_off_t>(payload.length()));
95 curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, payload.c_str());
96 curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION,
RecvCB);
97 curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, buffer);
99 ret = curl_easy_perform(h_curl);
100 curl_easy_cleanup(h_curl);
101 if (ret != CURLE_OK) {
103 "Make lease acquire request failed: %d. Reply: %s", ret,
104 buffer->
data.c_str());
114 const std::string &session_token,
115 const std::string &repo_service_url,
119 CURLcode ret =
static_cast<CURLcode
>(0);
126 const std::string header_str =
127 std::string(
"Authorization: ") + key.
id() +
" " +
129 struct curl_slist *auth_header = NULL;
130 auth_header = curl_slist_append(auth_header, header_str.c_str());
131 curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);
133 curl_easy_setopt(h_curl, CURLOPT_URL,
134 (repo_service_url +
"/leases/" + session_token).c_str());
135 curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
136 static_cast<curl_off_t>(0));
137 curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, NULL);
138 curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION,
RecvCB);
139 curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, reply);
141 ret = curl_easy_perform(h_curl);
142 curl_easy_cleanup(h_curl);
143 if (ret != CURLE_OK) {
145 "Make lease drop request failed: %d. Reply: '%s'",
146 ret, reply->
data.c_str());
154 std::string *session_token,
157 if (buffer.
data.size() == 0 || session_token == NULL) {
168 if (result != NULL) {
169 const std::string status = result->string_value;
170 if (status ==
"ok") {
173 reply->
root(),
"session_token", JSON_STRING);
176 token->string_value);
177 *session_token = token->string_value;
180 }
else if (status ==
"path_busy") {
182 reply->
root(),
"time_remaining", JSON_STRING);
184 "Path busy. Time remaining = %s", (time_remaining != NULL) ?
185 time_remaining->string_value :
"UNKNOWN");
187 }
else if (status ==
"error") {
191 (reason != NULL) ? reason->string_value :
"");
203 if (buffer.
data.size() == 0) {
214 if (result != NULL) {
215 const std::string status = result->string_value;
216 if (status ==
"ok") {
219 }
else if (status ==
"invalid_token") {
221 }
else if (status ==
"error") {
225 (reason != NULL) ? reason->string_value :
"");
239 Publisher::Session::Session(
const Settings &settings_session)
248 Publisher::Session::Session(
const SettingsPublisher &settings_publisher,
258 settings_.service_endpoint = settings_publisher.storage().endpoint();
260 settings_publisher.transaction().lease_path();
263 settings_publisher.transaction().spool_area().gw_session_token();
269 keep_alive_ = has_lease_;
273 void Publisher::Session::SetKeepAlive(
bool value) {
278 void Publisher::Session::Acquire() {
284 throw EPublish(
"cannot read gateway key: " +
settings_.gw_key_path,
285 EPublish::kFailGatewayKey);
291 std::string session_token;
302 throw EPublish(
"cannot write session token: " +
settings_.token_path);
307 throw EPublish(
"lease path busy", EPublish::kFailLeaseBusy);
311 throw EPublish(
"cannot parse session token", EPublish::kFailLeaseBody);
315 void Publisher::Session::Drop() {
324 int fd_token = open(
settings_.token_path.c_str(), O_RDONLY);
328 throw EPublish(
"cannot read session token: " +
settings_.token_path,
329 EPublish::kFailGatewayKey);
333 throw EPublish(
"cannot read gateway key: " +
settings_.gw_key_path,
334 EPublish::kFailGatewayKey);
345 rvi = unlink(
settings_.token_path.c_str());
347 throw EPublish(
"cannot delete session token " +
settings_.token_path);
351 throw EPublish(
"cannot drop request reply", EPublish::kFailLeaseBody);
355 Publisher::Session::~Session() {
#define LogCvmfs(source, mask,...)
const SettingsRepository settings_
static JSON * SearchInObject(const JSON *json_object, const std::string &name, const json_type type)
std::string gw_key_path() const
std::string ToString(const bool with_suffix=false) const
assert((mem||(size==0))&&"Out Of Memory")
bool SafeWriteToFile(const std::string &content, const std::string &path, int mode)
static void MakeDropRequest(const gateway::GatewayKey &key, const std::string &session_token, const std::string &repo_service_url, int llvl, CurlBuffer *reply)
static CURL * PrepareCurl(const std::string &method)
std::string secret() const
bool FileExists(const std::string &path)
static JsonDocument * Create(const std::string &text)
size_t RecvCB(void *buffer, size_t size, size_t nmemb, void *userp)
string StringifyInt(const int64_t value)
bool SafeReadToString(int fd, std::string *final_result)
const SettingsKeychain & keychain() const
string Base64(const string &data)
static void MakeAcquireRequest(const gateway::GatewayKey &key, const std::string &repo_path, const std::string &repo_service_url, int llvl, CurlBuffer *buffer)
void HmacString(const std::string &key, const std::string &content, Any *any_digest)
GatewayKey ReadGatewayKey(const std::string &key_file_name)
static LeaseReply ParseDropReply(const CurlBuffer &buffer, int llvl)
static LeaseReply ParseAcquireReply(const CurlBuffer &buffer, std::string *session_token, int llvl)
const JSON * root() const