]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_metadata.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
14 #include "include/page.h"
18 #include "rgw_rest_s3.h"
19 #include "rgw_rest_metadata.h"
20 #include "rgw_client_io.h"
21 #include "common/errno.h"
22 #include "common/strtol.h"
23 #include "include/assert.h"
25 #define dout_context g_ceph_context
26 #define dout_subsys ceph_subsys_rgw
28 const string
RGWOp_Metadata_Get::name() {
29 return "get_metadata";
32 static inline void frame_metadata_key(req_state
*s
, string
& out
) {
34 string key
= s
->info
.args
.get("key", &exists
);
37 if (!s
->init_state
.url_bucket
.empty()) {
38 section
= s
->init_state
.url_bucket
;
47 out
+= string(":") + key
;
51 void RGWOp_Metadata_Get::execute() {
54 frame_metadata_key(s
, metadata_key
);
57 http_ret
= store
->meta_mgr
->get(metadata_key
, s
->formatter
);
59 dout(5) << "ERROR: can't get key: " << cpp_strerror(http_ret
) << dendl
;
66 const string
RGWOp_Metadata_List::name() {
67 return "list_metadata";
70 void RGWOp_Metadata_List::execute() {
71 string marker
= s
->info
.args
.get("marker");
72 bool max_entries_specified
;
73 string max_entries_str
= s
->info
.args
.get("max-entries", &max_entries_specified
);
75 bool extended_response
= (max_entries_specified
); /* for backward compatibility, if max-entries is not specified
76 we will send the old response format */
77 uint64_t max_entries
= 0;
79 if (max_entries_specified
) {
81 max_entries
= (unsigned)strict_strtol(max_entries_str
.c_str(), 10, &err
);
83 dout(5) << "Error parsing max-entries " << max_entries_str
<< dendl
;
91 frame_metadata_key(s
, metadata_key
);
96 http_ret
= store
->meta_mgr
->list_keys_init(metadata_key
, marker
, &handle
);
98 dout(5) << "ERROR: can't get key: " << cpp_strerror(http_ret
) << dendl
;
105 if (extended_response
) {
106 s
->formatter
->open_object_section("result");
109 s
->formatter
->open_array_section("keys");
114 left
= (max_entries_specified
? max_entries
- count
: max
);
115 http_ret
= store
->meta_mgr
->list_keys_next(handle
, left
, keys
, &truncated
);
117 dout(5) << "ERROR: lists_keys_next(): " << cpp_strerror(http_ret
)
122 for (list
<string
>::iterator iter
= keys
.begin(); iter
!= keys
.end();
124 s
->formatter
->dump_string("key", *iter
);
128 } while (truncated
&& left
> 0);
130 s
->formatter
->close_section();
132 if (extended_response
) {
133 encode_json("truncated", truncated
, s
->formatter
);
134 encode_json("count", count
, s
->formatter
);
136 encode_json("marker", store
->meta_mgr
->get_marker(handle
), s
->formatter
);
138 s
->formatter
->close_section();
140 store
->meta_mgr
->list_keys_complete(handle
);
145 int RGWOp_Metadata_Put::get_data(bufferlist
& bl
) {
151 cl
= atoll(s
->length
);
153 data
= (char *)malloc(cl
+ 1);
157 read_len
= recv_body(s
, data
, cl
);
158 if (cl
!= (size_t)read_len
) {
159 dout(10) << "recv_body incomplete" << dendl
;
165 bl
.append(data
, read_len
);
167 int chunk_size
= CEPH_PAGE_SIZE
;
168 const char *enc
= s
->info
.env
->get("HTTP_TRANSFER_ENCODING");
169 if (!enc
|| strcmp(enc
, "chunked")) {
170 return -ERR_LENGTH_REQUIRED
;
172 data
= (char *)malloc(chunk_size
);
177 read_len
= recv_body(s
, data
, chunk_size
);
182 bl
.append(data
, read_len
);
183 } while (read_len
== chunk_size
);
190 void RGWOp_Metadata_Put::execute() {
194 http_ret
= get_data(bl
);
199 http_ret
= do_aws4_auth_completion();
204 frame_metadata_key(s
, metadata_key
);
206 RGWMetadataHandler::sync_type_t sync_type
= RGWMetadataHandler::APPLY_ALWAYS
;
208 bool mode_exists
= false;
209 string mode_string
= s
->info
.args
.get("update-type", &mode_exists
);
211 bool parsed
= RGWMetadataHandler::string_to_sync_type(mode_string
,
219 http_ret
= store
->meta_mgr
->put(metadata_key
, bl
, sync_type
,
222 dout(5) << "ERROR: can't put key: " << cpp_strerror(http_ret
) << dendl
;
225 // translate internal codes into return header
226 if (http_ret
== STATUS_NO_APPLY
)
227 update_status
= "skipped";
228 else if (http_ret
== STATUS_APPLIED
)
229 update_status
= "applied";
232 void RGWOp_Metadata_Put::send_response() {
233 int http_return_code
= http_ret
;
234 if ((http_ret
== STATUS_NO_APPLY
) || (http_ret
== STATUS_APPLIED
))
235 http_return_code
= STATUS_NO_CONTENT
;
236 set_req_state_err(s
, http_return_code
);
238 stringstream ver_stream
;
239 ver_stream
<< "ver:" << ondisk_version
.ver
240 <<",tag:" << ondisk_version
.tag
;
241 dump_header_if_nonempty(s
, "RGWX_UPDATE_STATUS", update_status
);
242 dump_header_if_nonempty(s
, "RGWX_UPDATE_VERSION", ver_stream
.str());
246 void RGWOp_Metadata_Delete::execute() {
249 frame_metadata_key(s
, metadata_key
);
250 http_ret
= store
->meta_mgr
->remove(metadata_key
);
252 dout(5) << "ERROR: can't remove key: " << cpp_strerror(http_ret
) << dendl
;
258 void RGWOp_Metadata_Lock::execute() {
259 string duration_str
, lock_id
;
262 frame_metadata_key(s
, metadata_key
);
266 duration_str
= s
->info
.args
.get("length");
267 lock_id
= s
->info
.args
.get("lock_id");
269 if ((!s
->info
.args
.exists("key")) ||
270 (duration_str
.empty()) ||
272 dout(5) << "Error invalid parameter list" << dendl
;
280 dur
= strict_strtol(duration_str
.c_str(), 10, &err
);
281 if (!err
.empty() || dur
<= 0) {
282 dout(5) << "invalid length param " << duration_str
<< dendl
;
286 http_ret
= store
->meta_mgr
->lock_exclusive(metadata_key
, make_timespan(dur
), lock_id
);
287 if (http_ret
== -EBUSY
)
288 http_ret
= -ERR_LOCKED
;
291 void RGWOp_Metadata_Unlock::execute() {
295 frame_metadata_key(s
, metadata_key
);
299 lock_id
= s
->info
.args
.get("lock_id");
301 if ((!s
->info
.args
.exists("key")) ||
303 dout(5) << "Error invalid parameter list" << dendl
;
308 http_ret
= store
->meta_mgr
->unlock(metadata_key
, lock_id
);
311 RGWOp
*RGWHandler_Metadata::op_get() {
312 if (s
->info
.args
.exists("key"))
313 return new RGWOp_Metadata_Get
;
315 return new RGWOp_Metadata_List
;
318 RGWOp
*RGWHandler_Metadata::op_put() {
319 return new RGWOp_Metadata_Put
;
322 RGWOp
*RGWHandler_Metadata::op_delete() {
323 return new RGWOp_Metadata_Delete
;
326 RGWOp
*RGWHandler_Metadata::op_post() {
327 if (s
->info
.args
.exists("lock"))
328 return new RGWOp_Metadata_Lock
;
329 else if (s
->info
.args
.exists("unlock"))
330 return new RGWOp_Metadata_Unlock
;