42 const char* user_agent_string =
"cvmfs/" CVMFS_VERSION;
44 CURL* h_curl = curl_easy_init();
47 curl_easy_setopt(h_curl, CURLOPT_NOPROGRESS, 1L);
48 curl_easy_setopt(h_curl, CURLOPT_USERAGENT, user_agent_string);
49 curl_easy_setopt(h_curl, CURLOPT_MAXREDIRS, 50L);
50 curl_easy_setopt(h_curl, CURLOPT_CUSTOMREQUEST, method.c_str());
55 static size_t RecvCB(
void* buffer,
size_t size,
size_t nmemb,
void* userp) {
58 if (size * nmemb < 1) {
62 my_buffer->
data =
static_cast<char*
>(buffer);
64 return my_buffer->
data.size();
69 const std::string& repo_path,
70 const std::string& repo_service_url,
74 CURLcode ret =
static_cast<CURLcode
>(0);
78 const std::string payload =
"{\"path\" : \"" + repo_path +
79 "\", \"api_version\" : \"" +
87 cs.ApplySslCertificatePath(h_curl);
89 const std::string header_str =
90 std::string(
"Authorization: ") + key.
id() +
" " +
92 struct curl_slist* auth_header = NULL;
93 auth_header = curl_slist_append(auth_header, header_str.c_str());
94 curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);
97 curl_easy_setopt(h_curl, CURLOPT_URL, (repo_service_url +
"/leases").c_str());
98 curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
99 static_cast<curl_off_t>(payload.length()));
100 curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, payload.c_str());
101 curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION,
RecvCB);
102 curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, buffer);
104 ret = curl_easy_perform(h_curl);
105 curl_easy_cleanup(h_curl);
106 if (ret != CURLE_OK) {
108 "Make lease acquire request failed: %d. Reply: %s", ret,
109 buffer->
data.c_str());
119 const std::string &session_token,
120 const std::string &repo_service_url,
124 CURLcode ret =
static_cast<CURLcode
>(0);
132 cs.ApplySslCertificatePath(h_curl);
134 const std::string header_str =
135 std::string(
"Authorization: ") + key.
id() +
" " +
137 struct curl_slist *auth_header = NULL;
138 auth_header = curl_slist_append(auth_header, header_str.c_str());
139 curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);
141 curl_easy_setopt(h_curl, CURLOPT_URL,
142 (repo_service_url +
"/leases/" + session_token).c_str());
143 curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
144 static_cast<curl_off_t>(0));
145 curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, NULL);
146 curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION,
RecvCB);
147 curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, reply);
149 ret = curl_easy_perform(h_curl);
150 curl_easy_cleanup(h_curl);
151 if (ret != CURLE_OK) {
153 "Make lease drop request failed: %d. Reply: '%s'",
154 ret, reply->
data.c_str());
162 std::string *session_token,
165 if (buffer.
data.size() == 0 || session_token == NULL) {
176 if (result != NULL) {
177 const std::string status = result->string_value;
178 if (status ==
"ok") {
181 reply->
root(),
"session_token", JSON_STRING);
184 token->string_value);
185 *session_token = token->string_value;
188 }
else if (status ==
"path_busy") {
190 reply->
root(),
"time_remaining", JSON_STRING);
192 "Path busy. Time remaining = %s", (time_remaining != NULL) ?
193 time_remaining->string_value :
"UNKNOWN");
195 }
else if (status ==
"error") {
199 (reason != NULL) ? reason->string_value :
"");
211 if (buffer.
data.size() == 0) {
222 if (result != NULL) {
223 const std::string status = result->string_value;
224 if (status ==
"ok") {
227 }
else if (status ==
"invalid_token") {
229 }
else if (status ==
"error") {
233 (reason != NULL) ? reason->string_value :
"");
247 Publisher::Session::Session(
const Settings &settings_session)
256 Publisher::Session::Session(
const SettingsPublisher &settings_publisher,
266 settings_.service_endpoint = settings_publisher.storage().endpoint();
268 settings_publisher.transaction().lease_path();
271 settings_publisher.transaction().spool_area().gw_session_token();
277 keep_alive_ = has_lease_;
281 void Publisher::Session::SetKeepAlive(
bool value) {
286 void Publisher::Session::Acquire() {
292 throw EPublish(
"cannot read gateway key: " +
settings_.gw_key_path,
293 EPublish::kFailGatewayKey);
299 std::string session_token;
310 throw EPublish(
"cannot write session token: " +
settings_.token_path);
315 throw EPublish(
"lease path busy", EPublish::kFailLeaseBusy);
319 throw EPublish(
"cannot parse session token", EPublish::kFailLeaseBody);
323 void Publisher::Session::Drop() {
332 int fd_token = open(
settings_.token_path.c_str(), O_RDONLY);
336 throw EPublish(
"cannot read session token: " +
settings_.token_path,
337 EPublish::kFailGatewayKey);
341 throw EPublish(
"cannot read gateway key: " +
settings_.gw_key_path,
342 EPublish::kFailGatewayKey);
353 rvi = unlink(
settings_.token_path.c_str());
355 throw EPublish(
"cannot delete session token " +
settings_.token_path);
359 throw EPublish(
"gateway doesn't recognize the lease or cannot drop it",
360 EPublish::kFailLeaseBody);
364 Publisher::Session::~Session() {
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)
std::string GetHostname()
static JsonDocument * Create(const std::string &text)
void UseSystemCertificatePath()
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
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)