From f5d6be6ec950f21b0f0980c49deb7195370477de Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 31 May 2011 14:31:57 -0700 Subject: [PATCH] rgw: move generic xml parsing code to some shared location --- src/Makefile.am | 4 +- src/rgw/rgw_acl.cc | 144 +++++---------------------------------------- src/rgw/rgw_acl.h | 51 ++-------------- src/rgw/rgw_op.cc | 21 ++++++- src/rgw/rgw_xml.cc | 123 ++++++++++++++++++++++++++++++++++++++ src/rgw/rgw_xml.h | 91 ++++++++++++++++++++++++++++ 6 files changed, 256 insertions(+), 178 deletions(-) create mode 100644 src/rgw/rgw_xml.cc create mode 100644 src/rgw/rgw_xml.h diff --git a/src/Makefile.am b/src/Makefile.am index 39bd03253d697..ec6a47f76117b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -290,7 +290,8 @@ bin_DEBUGPROGRAMS += testlibrbd testlibrbdpp if WITH_RADOSGW my_libradosgw_src = \ rgw/librgw.cc \ - rgw/rgw_acl.cc + rgw/rgw_acl.cc \ + rgw/rgw_xml.cc my_radosgw_src = \ rgw/rgw_fs.cc \ @@ -1082,6 +1083,7 @@ noinst_HEADERS = \ perfglue/heap_profiler.h\ rgw/rgw_access.h\ rgw/rgw_acl.h\ + rgw/rgw_xml.h\ rgw/rgw_cache.h\ rgw/rgw_common.h\ rgw/rgw_formats.h\ diff --git a/src/rgw/rgw_acl.cc b/src/rgw/rgw_acl.cc index a213f9b34dbf7..92cea40de37d8 100644 --- a/src/rgw/rgw_acl.cc +++ b/src/rgw/rgw_acl.cc @@ -13,118 +13,6 @@ using namespace std; static string rgw_uri_all_users = RGW_URI_ALL_USERS; static string rgw_uri_auth_users = RGW_URI_AUTH_USERS; -XMLObjIter:: -XMLObjIter() -{ -} - -XMLObjIter:: -~XMLObjIter() -{ -} - -void XMLObjIter:: -set(const XMLObjIter::map_iter_t &_cur, const XMLObjIter::map_iter_t &_end) -{ - cur = _cur; - end = _end; -} - -XMLObj *XMLObjIter:: -get_next() -{ - XMLObj *obj = NULL; - if (cur != end) { - obj = cur->second; - ++cur; - } - return obj; -}; - -ostream& operator<<(ostream& out, XMLObj& obj) { - out << obj.type << ": " << obj.data; - return out; -} - -XMLObj:: -~XMLObj() -{ -} - -bool XMLObj:: -xml_start(XMLObj *parent, const char *el, const char **attr) -{ - this->parent = parent; - type = el; - for (int i = 0; attr[i]; i += 2) { - attr_map[attr[i]] = string(attr[i + 1]); - } - return true; -} - -bool XMLObj:: -xml_end(const char *el) -{ - return true; -} - -void XMLObj:: -xml_handle_data(const char *s, int len) -{ - data = string(s, len); -} - -string& XMLObj:: -XMLObj::get_data() -{ - return data; -} - -XMLObj *XMLObj:: -XMLObj::get_parent() -{ - return parent; -} - -void XMLObj:: -add_child(string el, XMLObj *obj) -{ - children.insert(pair(el, obj)); -} - -bool XMLObj:: -get_attr(string name, string& attr) -{ - map::iterator iter = attr_map.find(name); - if (iter == attr_map.end()) - return false; - attr = iter->second; - return true; -} - -XMLObjIter XMLObj:: -find(string name) -{ - XMLObjIter iter; - map::iterator first; - map::iterator last; - first = children.find(name); - last = children.upper_bound(name); - iter.set(first, last); - return iter; -} - -XMLObj *XMLObj:: -find_first(string name) -{ - XMLObjIter iter; - map::iterator first; - first = children.find(name); - if (first != children.end()) - return first->second; - return NULL; -} - ACLPermission:: ACLPermission() : flags(0) { @@ -521,20 +409,20 @@ int RGWAccessControlPolicy::get_perm(string& id, int perm_mask) { return perm; } -void xml_start(void *data, const char *el, const char **attr) { - RGWXMLParser *handler = (RGWXMLParser *)data; +static void xml_start(void *data, const char *el, const char **attr) { + RGWACLXMLParser *handler = (RGWACLXMLParser *)data; if (!handler->xml_start(el, attr)) handler->set_failure(); } -RGWXMLParser:: -RGWXMLParser() : buf(NULL), buf_len(0), cur_obj(NULL), success(true) +RGWACLXMLParser:: +RGWACLXMLParser() : buf(NULL), buf_len(0), cur_obj(NULL), success(true) { } -RGWXMLParser:: -~RGWXMLParser() +RGWACLXMLParser:: +~RGWACLXMLParser() { free(buf); vector::iterator iter; @@ -544,7 +432,7 @@ RGWXMLParser:: } } -bool RGWXMLParser::xml_start(const char *el, const char **attr) { +bool RGWACLXMLParser::xml_start(const char *el, const char **attr) { XMLObj * obj; if (strcmp(el, "AccessControlPolicy") == 0) { obj = new RGWAccessControlPolicy(); @@ -582,14 +470,14 @@ bool RGWXMLParser::xml_start(const char *el, const char **attr) { return true; } -void xml_end(void *data, const char *el) { - RGWXMLParser *handler = (RGWXMLParser *)data; +static void xml_end(void *data, const char *el) { + RGWACLXMLParser *handler = (RGWACLXMLParser *)data; if (!handler->xml_end(el)) handler->set_failure(); } -bool RGWXMLParser::xml_end(const char *el) { +bool RGWACLXMLParser::xml_end(const char *el) { XMLObj *parent_obj = cur_obj->get_parent(); if (!cur_obj->xml_end(el)) return false; @@ -597,24 +485,24 @@ bool RGWXMLParser::xml_end(const char *el) { return true; } -void handle_data(void *data, const char *s, int len) +static void handle_data(void *data, const char *s, int len) { - RGWXMLParser *handler = (RGWXMLParser *)data; + RGWACLXMLParser *handler = (RGWACLXMLParser *)data; handler->handle_data(s, len); } -void RGWXMLParser::handle_data(const char *s, int len) +void RGWACLXMLParser::handle_data(const char *s, int len) { cur_obj->xml_handle_data(s, len); } -bool RGWXMLParser::init() +bool RGWACLXMLParser::init() { p = XML_ParserCreate(NULL); if (!p) { - RGW_LOG(10) << "RGWXMLParser::init(): ERROR allocating memory" << dendl; + RGW_LOG(10) << "RGWACLXMLParser::init(): ERROR allocating memory" << dendl; return false; } XML_SetElementHandler(p, ::xml_start, ::xml_end); @@ -623,7 +511,7 @@ bool RGWXMLParser::init() return true; } -bool RGWXMLParser::parse(const char *_buf, int len, int done) +bool RGWACLXMLParser::parse(const char *_buf, int len, int done) { int pos = buf_len; buf = (char *)realloc(buf, buf_len + len); diff --git a/src/rgw/rgw_acl.h b/src/rgw/rgw_acl.h index a9608ba974c3f..6372624ceebc6 100644 --- a/src/rgw/rgw_acl.h +++ b/src/rgw/rgw_acl.h @@ -8,6 +8,8 @@ #include +#include "rgw_xml.h" + using namespace std; @@ -22,49 +24,6 @@ using namespace std; RGW_PERM_READ_ACP | RGW_PERM_WRITE_ACP ) #define RGW_PERM_ALL RGW_PERM_FULL_CONTROL -class XMLObj; - -class XMLObjIter { - typedef map::iterator map_iter_t; - map_iter_t cur; - map_iter_t end; -public: - XMLObjIter(); - ~XMLObjIter(); - void set(const XMLObjIter::map_iter_t &_cur, const XMLObjIter::map_iter_t &_end); - XMLObj *get_next(); -}; - -/** - * Represents a block of XML. - * Give the class an XML blob, and it will parse the blob into - * an attr_name->value map. - * This really ought to be an abstract class or something; it - * shouldn't be the startpoint for any parsing. Look at RGWXMLParser for that. - */ -class XMLObj -{ - XMLObj *parent; - string type; -protected: - string data; - multimap children; - map attr_map; -public: - virtual ~XMLObj(); - bool xml_start(XMLObj *parent, const char *el, const char **attr); - virtual bool xml_end(const char *el); - virtual void xml_handle_data(const char *s, int len); - string& get_data(); - XMLObj *get_parent(); - void add_child(string el, XMLObj *obj); - bool get_attr(string name, string& attr); - XMLObjIter find(string name); - XMLObj *find_first(string name); - - friend ostream& operator<<(ostream& out, XMLObj& obj); -}; - class ACLPermission : public XMLObj { int flags; @@ -363,7 +322,7 @@ WRITE_CLASS_ENCODER(RGWAccessControlPolicy) * Interfaces with the webserver's XML handling code * to parse it in a way that makes sense for the rgw. */ -class RGWXMLParser : public XMLObj +class RGWACLXMLParser : public XMLObj { XML_Parser p; char *buf; @@ -371,8 +330,8 @@ class RGWXMLParser : public XMLObj XMLObj *cur_obj; vector objs; public: - RGWXMLParser(); - ~RGWXMLParser(); + RGWACLXMLParser(); + ~RGWACLXMLParser(); bool init(); bool xml_start(const char *el, const char **attr); bool xml_end(const char *el); diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 206de5fa1416f..704e5f8127089 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -410,6 +410,21 @@ void RGWPutObj::execute() } MD5 hash; + string obj; + if (!s->args.exists("uploadId")) { + obj = s->object_str; + } else { + obj = s->object_str; + obj.append("."); + obj.append(s->args.get("uploadId")); + string partNum = s->args.get("partNumber"); + if (partNum.empty()) { + ret = -EINVAL; + goto done; + } + obj.append("."); + obj.append(partNum); + } do { get_data(); if (len > 0) { @@ -417,7 +432,7 @@ void RGWPutObj::execute() // For the first call to put_obj_data, pass -1 as the offset to // do a write_full. ret = rgwstore->put_obj_data(s->user.user_id, s->bucket_str, - s->object_str, data, + obj, data, ((ofs == 0) ? -1 : ofs), len, NULL); free(data); if (ret < 0) @@ -454,7 +469,7 @@ void RGWPutObj::execute() get_request_metadata(s, attrs); - ret = rgwstore->put_obj_meta(s->user.user_id, s->bucket_str, s->object_str, NULL, attrs, false); + ret = rgwstore->put_obj_meta(s->user.user_id, s->bucket_str, obj, NULL, attrs, false); } done: send_response(); @@ -682,7 +697,7 @@ void RGWPutACLs::execute() bufferlist bl; RGWAccessControlPolicy *policy = NULL; - RGWXMLParser parser; + RGWACLXMLParser parser; RGWAccessControlPolicy new_policy; stringstream ss; char *orig_data = data; diff --git a/src/rgw/rgw_xml.cc b/src/rgw/rgw_xml.cc new file mode 100644 index 0000000000000..d18c4730564f9 --- /dev/null +++ b/src/rgw/rgw_xml.cc @@ -0,0 +1,123 @@ +#include + +#include +#include + +#include "include/types.h" + +#include "rgw_xml.h" + +using namespace std; + +XMLObjIter:: +XMLObjIter() +{ +} + +XMLObjIter:: +~XMLObjIter() +{ +} + +void XMLObjIter:: +set(const XMLObjIter::map_iter_t &_cur, const XMLObjIter::map_iter_t &_end) +{ + cur = _cur; + end = _end; +} + +XMLObj *XMLObjIter:: +get_next() +{ + XMLObj *obj = NULL; + if (cur != end) { + obj = cur->second; + ++cur; + } + return obj; +}; + +ostream& operator<<(ostream& out, XMLObj& obj) { + out << obj.type << ": " << obj.data; + return out; +} + +XMLObj:: +~XMLObj() +{ +} + +bool XMLObj:: +xml_start(XMLObj *parent, const char *el, const char **attr) +{ + this->parent = parent; + type = el; + for (int i = 0; attr[i]; i += 2) { + attr_map[attr[i]] = string(attr[i + 1]); + } + return true; +} + +bool XMLObj:: +xml_end(const char *el) +{ + return true; +} + +void XMLObj:: +xml_handle_data(const char *s, int len) +{ + data = string(s, len); +} + +string& XMLObj:: +XMLObj::get_data() +{ + return data; +} + +XMLObj *XMLObj:: +XMLObj::get_parent() +{ + return parent; +} + +void XMLObj:: +add_child(string el, XMLObj *obj) +{ + children.insert(pair(el, obj)); +} + +bool XMLObj:: +get_attr(string name, string& attr) +{ + map::iterator iter = attr_map.find(name); + if (iter == attr_map.end()) + return false; + attr = iter->second; + return true; +} + +XMLObjIter XMLObj:: +find(string name) +{ + XMLObjIter iter; + map::iterator first; + map::iterator last; + first = children.find(name); + last = children.upper_bound(name); + iter.set(first, last); + return iter; +} + +XMLObj *XMLObj:: +find_first(string name) +{ + XMLObjIter iter; + map::iterator first; + first = children.find(name); + if (first != children.end()) + return first->second; + return NULL; +} + diff --git a/src/rgw/rgw_xml.h b/src/rgw/rgw_xml.h new file mode 100644 index 0000000000000..2d99dbac7f8ed --- /dev/null +++ b/src/rgw/rgw_xml.h @@ -0,0 +1,91 @@ +#ifndef CEPH_RGW_XML_H +#define CEPH_RGW_XML_H + +#include +#include +#include +#include + +#include + +using namespace std; + + +#define RGW_URI_ALL_USERS "http://acs.amazonaws.com/groups/global/AllUsers" +#define RGW_URI_AUTH_USERS "http://acs.amazonaws.com/groups/global/AuthenticatedUsers" + +#define RGW_PERM_READ 0x01 +#define RGW_PERM_WRITE 0x02 +#define RGW_PERM_READ_ACP 0x04 +#define RGW_PERM_WRITE_ACP 0x08 +#define RGW_PERM_FULL_CONTROL ( RGW_PERM_READ | RGW_PERM_WRITE | \ + RGW_PERM_READ_ACP | RGW_PERM_WRITE_ACP ) +#define RGW_PERM_ALL RGW_PERM_FULL_CONTROL + +class XMLObj; + +class XMLObjIter { + typedef map::iterator map_iter_t; + map_iter_t cur; + map_iter_t end; +public: + XMLObjIter(); + ~XMLObjIter(); + void set(const XMLObjIter::map_iter_t &_cur, const XMLObjIter::map_iter_t &_end); + XMLObj *get_next(); +}; + +/** + * Represents a block of XML. + * Give the class an XML blob, and it will parse the blob into + * an attr_name->value map. + * This really ought to be an abstract class or something; it + * shouldn't be the startpoint for any parsing. Look at RGWXMLParser for that. + */ +class XMLObj +{ + XMLObj *parent; + string type; +protected: + string data; + multimap children; + map attr_map; +public: + virtual ~XMLObj(); + bool xml_start(XMLObj *parent, const char *el, const char **attr); + virtual bool xml_end(const char *el); + virtual void xml_handle_data(const char *s, int len); + string& get_data(); + XMLObj *get_parent(); + void add_child(string el, XMLObj *obj); + bool get_attr(string name, string& attr); + XMLObjIter find(string name); + XMLObj *find_first(string name); + + friend ostream& operator<<(ostream& out, XMLObj& obj); +}; + +class RGWXMLParser : public XMLObj +{ + XML_Parser p; + char *buf; + int buf_len; + XMLObj *cur_obj; + vector objs; +public: + RGWXMLParser(); + ~RGWXMLParser(); + bool init(); + bool xml_start(const char *el, const char **attr); + bool xml_end(const char *el); + void handle_data(const char *s, int len); + + bool parse(const char *buf, int len, int done); + const char *get_xml() { return buf; } + void set_failure() { success = false; } + +private: + bool success; +}; + +#endif -- 2.39.5