41 const char *user_agent_string =
"cvmfs/" 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();
67 const std::string &repo_path,
68 const std::string &repo_service_url,
71 CURLcode ret =
static_cast<CURLcode
>(0);
75 const std::string payload =
"{\"path\" : \"" + repo_path
76 +
"\", \"api_version\" : \""
84 cs.ApplySslCertificatePath(h_curl);
86 const std::string header_str = std::string(
"Authorization: ") + key.
id() +
" "
88 struct curl_slist *auth_header = NULL;
89 auth_header = curl_slist_append(auth_header, header_str.c_str());
90 curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);
93 curl_easy_setopt(h_curl, CURLOPT_URL, (repo_service_url +
"/leases").c_str());
94 curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
95 static_cast<curl_off_t>(payload.length()));
96 curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, payload.c_str());
97 curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION,
RecvCB);
98 curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, buffer);
100 ret = curl_easy_perform(h_curl);
101 curl_easy_cleanup(h_curl);
102 if (ret != CURLE_OK) {
104 "Make lease acquire request failed: %d. Reply: %s", ret,
105 buffer->
data.c_str());
114 const std::string &session_token,
115 const std::string &repo_service_url,
118 CURLcode ret =
static_cast<CURLcode
>(0);
126 cs.ApplySslCertificatePath(h_curl);
128 const std::string header_str = std::string(
"Authorization: ") + key.
id() +
" "
130 struct curl_slist *auth_header = NULL;
131 auth_header = curl_slist_append(auth_header, header_str.c_str());
132 curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);
134 curl_easy_setopt(h_curl, CURLOPT_URL,
135 (repo_service_url +
"/leases/" + session_token).c_str());
136 curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
137 static_cast<curl_off_t>(0));
138 curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, NULL);
139 curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION,
RecvCB);
140 curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, reply);
142 ret = curl_easy_perform(h_curl);
143 curl_easy_cleanup(h_curl);
144 if (ret != CURLE_OK) {
146 "Make lease drop request failed: %d. Reply: '%s'", ret,
147 reply->
data.c_str());
154 std::string *session_token,
156 if (buffer.
data.size() == 0 || session_token == NULL) {
167 if (result != NULL) {
168 const std::string status = result->string_value;
169 if (status ==
"ok") {
172 reply->
root(),
"session_token", JSON_STRING);
175 token->string_value);
176 *session_token = token->string_value;
179 }
else if (status ==
"path_busy") {
181 reply->
root(),
"time_remaining", JSON_STRING);
184 (time_remaining != NULL) ? time_remaining->string_value :
"UNKNOWN");
186 }
else if (status ==
"error") {
190 (reason != NULL) ? reason->string_value :
"");
202 if (buffer.
data.size() == 0) {
213 if (result != NULL) {
214 const std::string status = result->string_value;
215 if (status ==
"ok") {
218 }
else if (status ==
"invalid_token") {
220 }
else if (status ==
"error") {
224 (reason != NULL) ? reason->string_value :
"");
238 Publisher::Session::Session(
const Settings &settings_session)
245 Publisher::Session::Session(
const SettingsPublisher &settings_publisher,
248 if (settings_publisher.storage().type()
254 settings_.service_endpoint = settings_publisher.storage().endpoint();
256 + settings_publisher.transaction().lease_path();
258 settings_.token_path = settings_publisher.transaction()
266 keep_alive_ = has_lease_;
270 void Publisher::Session::SetKeepAlive(
bool value) { keep_alive_ = value; }
273 void Publisher::Session::Acquire() {
279 throw EPublish(
"cannot read gateway key: " +
settings_.gw_key_path,
280 EPublish::kFailGatewayKey);
286 std::string session_token;
293 throw EPublish(
"cannot write session token: " +
settings_.token_path);
297 throw EPublish(
"lease path busy", EPublish::kFailLeaseBusy);
301 throw EPublish(
"cannot parse session token", EPublish::kFailLeaseBody);
305 void Publisher::Session::Drop() {
314 int fd_token = open(
settings_.token_path.c_str(), O_RDONLY);
318 throw EPublish(
"cannot read session token: " +
settings_.token_path,
319 EPublish::kFailGatewayKey);
323 throw EPublish(
"cannot read gateway key: " +
settings_.gw_key_path,
324 EPublish::kFailGatewayKey);
335 rvi = unlink(
settings_.token_path.c_str());
337 throw EPublish(
"cannot delete session token " +
settings_.token_path);
341 throw EPublish(
"gateway doesn't recognize the lease or cannot drop it",
342 EPublish::kFailLeaseBody);
346 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,...)