#define CEPH_RGW_COMMON_H
#include "common/ceph_crypto.h"
+
#include "common/debug.h"
#include "common/perf_counters.h"
/* start */
std::string object_name = full_object_name();
f->write_req =
- new RGWWriteRequest(fs->get_context(), fs->get_user(), bucket_name(),
- object_name);
+ new RGWWriteRequest(fs->get_context(), fs->get_user(), this,
+ bucket_name(), object_name);
rc = librgw.get_fe()->start_req(f->write_req);
}
int RGWWriteRequest::exec_finish()
{
- return 0;
+ bufferlist bl, aclbl;
+ map<string, bufferlist> attrs;
+ map<string, string>::iterator iter;
+ char calc_md5[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1];
+ unsigned char m[CEPH_CRYPTO_MD5_DIGESTSIZE];
+ struct req_state* s = get_state();
+
+ s->obj_size = ofs; // XXX check ofs
+ perfcounter->inc(l_rgw_put_b, s->obj_size);
+
+ op_ret = get_store()->check_quota(s->bucket_owner.get_id(), s->bucket,
+ user_quota, bucket_quota, s->obj_size);
+ if (op_ret < 0) {
+ goto done;
+ }
+
+ if (need_calc_md5) {
+ processor->complete_hash(&hash);
+ }
+ hash.Final(m);
+
+ buf_to_hex(m, CEPH_CRYPTO_MD5_DIGESTSIZE, calc_md5);
+ etag = calc_md5;
+
+#if 0 /* XXX only in PostObj currently */
+ if (supplied_md5_b64 && strcmp(calc_md5, supplied_md5)) {
+ op_ret = -ERR_BAD_DIGEST;
+ goto done;
+ }
+#endif
+
+ policy.encode(aclbl);
+
+ attrs[RGW_ATTR_ACL] = aclbl;
+
+ /* XXX most of the following cases won't currently arise */
+ if (unlikely(!! dlo_manifest)) {
+ op_ret = encode_dlo_manifest_attr(dlo_manifest, attrs);
+ if (op_ret < 0) {
+ ldout(s->cct, 0) << "bad user manifest: " << dlo_manifest << dendl;
+ goto done;
+ }
+ complete_etag(hash, &etag);
+ ldout(s->cct, 10) << __func__ << ": calculated md5 for user manifest: "
+ << etag << dendl;
+ }
+
+ if (unlikely(!! slo_info)) {
+ bufferlist manifest_bl;
+ ::encode(*slo_info, manifest_bl);
+ attrs[RGW_ATTR_SLO_MANIFEST] = manifest_bl;
+
+ hash.Update((byte *)slo_info->raw_data, slo_info->raw_data_len);
+ complete_etag(hash, &etag);
+ ldout(s->cct, 10) << __func__ << ": calculated md5 for user manifest: "
+ << etag << dendl;
+ }
+
+ if (supplied_etag && etag.compare(supplied_etag) != 0) {
+ op_ret = -ERR_UNPROCESSABLE_ENTITY;
+ goto done;
+ }
+ bl.append(etag.c_str(), etag.size() + 1);
+ attrs[RGW_ATTR_ETAG] = bl;
+
+ for (iter = s->generic_attrs.begin(); iter != s->generic_attrs.end();
+ ++iter) {
+ bufferlist& attrbl = attrs[iter->first];
+ const string& val = iter->second;
+ attrbl.append(val.c_str(), val.size() + 1);
+ }
+
+ rgw_get_request_metadata(s->cct, s->info, attrs);
+ encode_delete_at_attr(delete_at, attrs);
+
+ /* Add a custom metadata to expose the information whether an object
+ * is an SLO or not. Appending the attribute must be performed AFTER
+ * processing any input from user in order to prohibit overwriting. */
+ if (unlikely(!! slo_info)) {
+ bufferlist slo_userindicator_bl;
+ ::encode("True", slo_userindicator_bl);
+ attrs[RGW_ATTR_SLO_UINDICATOR] = slo_userindicator_bl;
+ }
+
+ op_ret = processor->complete(etag, &mtime, 0, attrs, delete_at, if_match,
+ if_nomatch);
+
+done:
+ dispose_processor(processor);
+ perfcounter->tinc(l_rgw_put_lat,
+ (ceph_clock_now(s->cct) - s->time));
+ return op_ret;
} /* exec_finish */
/* librgw */
public:
const std::string& bucket_name;
const std::string& obj_name;
+ RGWFileHandle* rgw_fh;
RGWPutObjProcessor *processor;
buffer::list data;
MD5 hash;
bool multipart;
bool need_calc_md5;
- RGWWriteRequest(CephContext* _cct, RGWUserInfo *_user,
+ RGWWriteRequest(CephContext* _cct, RGWUserInfo *_user, RGWFileHandle* _fh,
const std::string& _bname, const std::string& _oname)
: RGWLibContinuedReq(_cct, _user), bucket_name(_bname), obj_name(_oname),
- processor(nullptr), last_off(0), next_off(0), bytes_written(0),
- multipart(false) {
+ rgw_fh(_fh), processor(nullptr), last_off(0), next_off(0),
+ bytes_written(0), multipart(false) {
magic = 81;
op = this;
}
return r;
}
-static void format_xattr(std::string &xattr)
-{
- /* If the extended attribute is not valid UTF-8, we encode it using quoted-printable
- * encoding.
- */
- if ((check_utf8(xattr.c_str(), xattr.length()) != 0) ||
- (check_for_control_characters(xattr.c_str(), xattr.length()) != 0)) {
- static const char MIME_PREFIX_STR[] = "=?UTF-8?Q?";
- static const int MIME_PREFIX_LEN = sizeof(MIME_PREFIX_STR) - 1;
- static const char MIME_SUFFIX_STR[] = "?=";
- static const int MIME_SUFFIX_LEN = sizeof(MIME_SUFFIX_STR) - 1;
- int mlen = mime_encode_as_qp(xattr.c_str(), NULL, 0);
- char *mime = new char[MIME_PREFIX_LEN + mlen + MIME_SUFFIX_LEN + 1];
- strcpy(mime, MIME_PREFIX_STR);
- mime_encode_as_qp(xattr.c_str(), mime + MIME_PREFIX_LEN, mlen);
- strcpy(mime + MIME_PREFIX_LEN + (mlen - 1), MIME_SUFFIX_STR);
- xattr.assign(mime);
- delete [] mime;
- }
-}
-
-/**
- * Get the HTTP request metadata out of the req_state as a
- * map(<attr_name, attr_contents>, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME)
- * s: The request state
- * attrs: will be filled up with attrs mapped as <attr_name, attr_contents>
- *
- */
-static void rgw_get_request_metadata(CephContext *cct,
- struct req_info& info,
- map<string, bufferlist>& attrs,
- const bool allow_empty_attrs = true)
-{
- map<string, string>::iterator iter;
- for (iter = info.x_meta_map.begin(); iter != info.x_meta_map.end(); ++iter) {
- const string &name(iter->first);
- string &xattr(iter->second);
-
- if (allow_empty_attrs || !xattr.empty()) {
- ldout(cct, 10) << "x>> " << name << ":" << xattr << dendl;
- format_xattr(xattr);
- string attr_name(RGW_ATTR_PREFIX);
- attr_name.append(name);
- map<string, bufferlist>::value_type v(attr_name, bufferlist());
- std::pair < map<string, bufferlist>::iterator, bool > rval(attrs.insert(v));
- bufferlist& bl(rval.first->second);
- bl.append(xattr.c_str(), xattr.size() + 1);
- }
- }
-}
-
static int decode_policy(CephContext *cct, bufferlist& bl, RGWAccessControlPolicy *policy)
{
bufferlist::iterator iter = bl.begin();
rgw_bucket_object_pre_exec(s);
}
-static void encode_delete_at_attr(time_t delete_at, map<string, bufferlist>& attrs)
-{
- if (delete_at == 0) {
- return;
- }
-
- bufferlist delatbl;
- ::encode(utime_t(delete_at, 0), delatbl);
- attrs[RGW_ATTR_DELETE_AT] = delatbl;
-}
-
-static int encode_dlo_manifest_attr(const char * const dlo_manifest,
- map<string, bufferlist>& attrs)
-{
- string dm = dlo_manifest;
-
- if (dm.find('/') == string::npos) {
- return -EINVAL;
- }
-
- bufferlist manifest_bl;
- manifest_bl.append(dlo_manifest, strlen(dlo_manifest) + 1);
- attrs[RGW_ATTR_USER_MANIFEST] = manifest_bl;
-
- return 0;
-}
-
-static void complete_etag(MD5& hash, string *etag)
-{
- char etag_buf[CEPH_CRYPTO_MD5_DIGESTSIZE];
- char etag_buf_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
-
- hash.Final((byte *)etag_buf);
- buf_to_hex((const unsigned char *)etag_buf, CEPH_CRYPTO_MD5_DIGESTSIZE, etag_buf_str);
-
- *etag = etag_buf_str;
-}
-
void RGWPutObj::execute()
{
RGWPutObjProcessor *processor = NULL;
#include <set>
#include <map>
+#include "common/armor.h"
+#include "common/mime.h"
+#include "common/utf8.h"
+#include "common/ceph_json.h"
+#include "common/utf8.h"
+
#include "rgw_common.h"
#include "rgw_rados.h"
#include "rgw_user.h"
#include "rgw_cors.h"
#include "rgw_quota.h"
+#include "include/assert.h"
+
using namespace std;
struct req_state;
return 0;
} /* get_system_versioning_params */
+static inline void format_xattr(std::string &xattr)
+{
+ /* If the extended attribute is not valid UTF-8, we encode it using
+ * quoted-printable encoding.
+ */
+ if ((check_utf8(xattr.c_str(), xattr.length()) != 0) ||
+ (check_for_control_characters(xattr.c_str(), xattr.length()) != 0)) {
+ static const char MIME_PREFIX_STR[] = "=?UTF-8?Q?";
+ static const int MIME_PREFIX_LEN = sizeof(MIME_PREFIX_STR) - 1;
+ static const char MIME_SUFFIX_STR[] = "?=";
+ static const int MIME_SUFFIX_LEN = sizeof(MIME_SUFFIX_STR) - 1;
+ int mlen = mime_encode_as_qp(xattr.c_str(), NULL, 0);
+ char *mime = new char[MIME_PREFIX_LEN + mlen + MIME_SUFFIX_LEN + 1];
+ strcpy(mime, MIME_PREFIX_STR);
+ mime_encode_as_qp(xattr.c_str(), mime + MIME_PREFIX_LEN, mlen);
+ strcpy(mime + MIME_PREFIX_LEN + (mlen - 1), MIME_SUFFIX_STR);
+ xattr.assign(mime);
+ delete [] mime;
+ }
+} /* format_xattr */
+
+/**
+ * Get the HTTP request metadata out of the req_state as a
+ * map(<attr_name, attr_contents>, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME)
+ * s: The request state
+ * attrs: will be filled up with attrs mapped as <attr_name, attr_contents>
+ *
+ */
+static inline void rgw_get_request_metadata(CephContext *cct,
+ struct req_info& info,
+ map<string, bufferlist>& attrs,
+ const bool allow_empty_attrs = true)
+{
+ map<string, string>::iterator iter;
+ for (iter = info.x_meta_map.begin(); iter != info.x_meta_map.end(); ++iter) {
+ const string &name(iter->first);
+ string &xattr(iter->second);
+
+ if (allow_empty_attrs || !xattr.empty()) {
+ lsubdout(cct, rgw, 10) << "x>> " << name << ":" << xattr << dendl;
+ format_xattr(xattr);
+ string attr_name(RGW_ATTR_PREFIX);
+ attr_name.append(name);
+ map<string, bufferlist>::value_type v(attr_name, bufferlist());
+ std::pair < map<string, bufferlist>::iterator, bool >
+ rval(attrs.insert(v));
+ bufferlist& bl(rval.first->second);
+ bl.append(xattr.c_str(), xattr.size() + 1);
+ }
+ }
+} /* rgw_get_request_metadata */
+
+static inline void encode_delete_at_attr(time_t delete_at,
+ map<string, bufferlist>& attrs)
+{
+ if (delete_at == 0) {
+ return;
+ }
+
+ bufferlist delatbl;
+ ::encode(utime_t(delete_at, 0), delatbl);
+ attrs[RGW_ATTR_DELETE_AT] = delatbl;
+} /* encode_delete_at_attr */
+
+static inline int encode_dlo_manifest_attr(const char * const dlo_manifest,
+ map<string, bufferlist>& attrs)
+{
+ string dm = dlo_manifest;
+
+ if (dm.find('/') == string::npos) {
+ return -EINVAL;
+ }
+
+ bufferlist manifest_bl;
+ manifest_bl.append(dlo_manifest, strlen(dlo_manifest) + 1);
+ attrs[RGW_ATTR_USER_MANIFEST] = manifest_bl;
+
+ return 0;
+} /* encode_dlo_manifest_attr */
+
+static inline void complete_etag(MD5& hash, string *etag)
+{
+ char etag_buf[CEPH_CRYPTO_MD5_DIGESTSIZE];
+ char etag_buf_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
+
+ hash.Final((byte *)etag_buf);
+ buf_to_hex((const unsigned char *)etag_buf, CEPH_CRYPTO_MD5_DIGESTSIZE,
+ etag_buf_str);
+
+ *etag = etag_buf_str;
+} /* complete_etag */
+
#endif /* CEPH_RGW_OP_H */
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
+#include "include/assert.h"
+
#include "common/Formatter.h"
#include "common/utf8.h"
+#include "common/ceph_json.h"
+
#include "rgw_swift.h"
#include "rgw_rest_swift.h"
#include "rgw_acl_swift.h"
#ifndef CEPH_RGW_SWIFT_H
#define CEPH_RGW_SWIFT_H
+#include "include/assert.h"
+
#include "rgw_common.h"
#include "common/Cond.h"