From 9847eb8b9fb5864019e0fe0f2da448c2796f02b6 Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Mon, 2 May 2011 11:51:58 -0700 Subject: [PATCH] rgw: put XML-to-bin translation into a librgw Signed-off-by: Colin McCabe --- src/Makefile.am | 57 +++++++++++++++++++----- src/include/rados/librgw.h | 31 +++++++++++++ src/obsync/obsync.py | 2 +- src/rgw/librgw.cc | 91 ++++++++++++++++++++++++++++++++++++++ src/test/librgw.cc | 89 +++++++++++++++++++++++++++++++++++++ 5 files changed, 259 insertions(+), 11 deletions(-) create mode 100644 src/include/rados/librgw.h create mode 100644 src/rgw/librgw.cc create mode 100644 src/test/librgw.cc diff --git a/src/Makefile.am b/src/Makefile.am index 05ba14702f536..e89fa616838e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -245,6 +245,25 @@ librados_a_SOURCES = ${librados_SOURCES} librados_a_CFLAGS = ${CRYPTO_CFLAGS} ${AM_CFLAGS} librados_a_CXXFLAGS = ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS} +# librgw +if WITH_RADOSGW +librgw_SOURCES = \ + $(my_radosgw_src) \ + rgw/librgw.cc + ${libcommon_a_SOURCES} +librgw_la_SOURCES = ${librgw_SOURCES} +librgw_la_CFLAGS = ${CRYPTO_CFLAGS} ${AM_CFLAGS} +librgw_la_CXXFLAGS = ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS} +librgw_la_LIBADD = libcrush.la -lpthread $(CRYPTO_LIBS) $(EXTRALIBS) +librgw_la_LDFLAGS = ${AM_LDFLAGS} -version-info 1:0:0 -export-symbols-regex '^librgw_.*' \ + -lexpat -lpthread -lm -lcurl +lib_LTLIBRARIES += librgw.la + +librgw_a_SOURCES = ${librgw_SOURCES} +librgw_a_CFLAGS = ${CRYPTO_CFLAGS} ${AM_CFLAGS} +librgw_a_CXXFLAGS = ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS} +endif + # librbd librbd_SOURCES = \ librbd.cc @@ -286,7 +305,7 @@ testlibrbdpp_LDADD = librbd.la librados.la libcrush.la -lpthread -lm \ bin_DEBUGPROGRAMS += testlibrbd testlibrbdpp if WITH_RADOSGW -libradosgw_a_SOURCES = \ +my_radosgw_src = \ rgw/rgw_fs.cc \ rgw/rgw_rados.cc \ rgw/rgw_acl.cc \ @@ -304,17 +323,16 @@ libradosgw_a_SOURCES = \ rgw/rgw_log.cc \ rgw/rgw_escape.c -libradosgw_a_CFLAGS = ${AM_CFLAGS} -libradosgw_a_CXXFLAGS = ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS} -#libradosgw_a_LDFLAGS = ${CRYPTO_LDFLAGS} ${AM_LDFLAGS} -# lib_LTLIBRARIES += libradosgw.a +my_radosgw_ldadd = \ + librgw.a librados.a libcrush.a -lfcgi -lcurl -lexpat \ + -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) -radosgw_SOURCES = rgw/rgw_main.cc -radosgw_LDADD = libradosgw.a librados.a libcrush.a -lfcgi -lexpat -lpthread -lm -lcurl $(CRYPTO_LIBS) $(EXTRALIBS) +radosgw_SOURCES = $(my_radosgw_src) rgw/rgw_main.cc +radosgw_LDADD = $(my_radosgw_ldadd) radosgw_CXXFLAGS = ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS} -radosgw_admin_SOURCES = rgw/rgw_admin.cc +radosgw_admin_SOURCES = $(my_radosgw_src) rgw/rgw_admin.cc radosgw_admin_CXXFLAGS = ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS} -radosgw_admin_LDADD = libradosgw.a librados.a libcrush.a -lfcgi -lexpat -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) +radosgw_admin_LDADD = $(my_radosgw_ldadd) bin_PROGRAMS += radosgw radosgw_admin endif @@ -444,6 +462,14 @@ unittest_confutils_LDADD = libcommon.a ${UNITTEST_LDADD} unittest_confutils_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} check_PROGRAMS += unittest_confutils +if WITH_RADOSGW +unittest_librgw_SOURCES = test/librgw.cc +unittest_librgw_LDFLAGS = -pthread -lcurl ${AM_LDFLAGS} +unittest_librgw_LDADD = librgw.a ${CRYPTO_LIBS} libcommon.a ${UNITTEST_LDADD} -lexpat -lfcgi +unittest_librgw_CXXFLAGS = ${CRYPTO_CFLAGS} ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} +check_PROGRAMS += unittest_librgw +endif + # shell scripts editpaths = sed \ -e 's|@bindir[@]|$(bindir)|g' \ @@ -492,7 +518,11 @@ endif noinst_LIBRARIES = \ libcommon.a libcrush.a \ libmon.a libmds.a libosdc.a libosd.a libclient.a \ - libos.a librados.a librbd.a libradosgw.a + libos.a librados.a librbd.a + +if WITH_RADOSGW +noinst_LIBRARIES += librgw.a +endif noinst_LIBRARIES += #libcephclient_so.a @@ -532,6 +562,12 @@ rados_include_DATA = \ $(srcdir)/include/page.h \ $(srcdir)/include/crc32c.h +if WITH_RADOSGW +rgw_includedir = $(includedir)/rados +rgw_include_DATA = \ + $(srcdir)/include/rados/librgw.h +endif + crush_includedir = $(includedir)/crush crush_include_DATA = \ $(srcdir)/crush/hash.h \ @@ -844,6 +880,7 @@ noinst_HEADERS = \ include/xlist.h\ include/rados/librados.h\ include/rados/librados.hpp\ + include/rados/librgw.h\ include/rados/page.h\ include/rados/crc32c.h\ include/rados/buffer.h\ diff --git a/src/include/rados/librgw.h b/src/include/rados/librgw.h new file mode 100644 index 0000000000000..21c70544edfaf --- /dev/null +++ b/src/include/rados/librgw.h @@ -0,0 +1,31 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_LIBRGW_H +#define CEPH_LIBRGW_H + +#ifdef __cplusplus +extern "C" { +#endif + +int librgw_acl_bin2xml(const char *bin, int bin_len, char **xml); +void librgw_free_xml(char *xml); +int librgw_acl_xml2bin(const char *xml, char **bin, int *bin_len); +void librgw_free_bin(char *bin); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/obsync/obsync.py b/src/obsync/obsync.py index 63cbeebcd24a5..da0b6ace98fa3 100755 --- a/src/obsync/obsync.py +++ b/src/obsync/obsync.py @@ -343,7 +343,7 @@ def test_acl_policy(): "" + \ "fooMrFoo" + \ "*** Owner-Canonical-User-ID ***" + \ +"xsi:type=\"CanonicalUser\">bar" + \ "display-name" + \ "FULL_CONTROL" test1 = AclPolicy.from_xml(test1_xml) diff --git a/src/rgw/librgw.cc b/src/rgw/librgw.cc new file mode 100644 index 0000000000000..06dfc7f097653 --- /dev/null +++ b/src/rgw/librgw.cc @@ -0,0 +1,91 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "include/types.h" +#include "include/rados/librgw.h" +#include "rgw/rgw_acl.h" +#include "rgw_acl.h" + +#include +#include +#include + +int librgw_acl_bin2xml(const char *bin, int bin_len, char **xml) +{ + try { + // convert to bufferlist + bufferlist bl; + bl.append(bin, bin_len); + + // convert to RGWAccessControlPolicy + RGWAccessControlPolicy acl; + bufferlist::iterator bli(bl.begin()); + acl.decode(bli); + + // convert to XML stringstream + stringstream ss; + acl.to_xml(ss); + + // convert to XML C string + *xml = strdup(ss.str().c_str()); + return 0; + } + catch (...) { + return -2000; + } +} + +void librgw_free_xml(char *xml) +{ + free(xml); +} + +int librgw_acl_xml2bin(const char *xml, char **bin, int *bin_len) +{ + try { + RGWXMLParser parser; + if (!parser.init()) { + return -1000; + } + if (!parser.parse(xml, strlen(xml), true)) { + return -EINVAL; + } + RGWAccessControlPolicy *policy = + (RGWAccessControlPolicy *)parser.find_first("AccessControlPolicy"); + if (!policy) { + return -1001; + } + bufferlist bl; + policy->encode(bl); + + char *bin_ = (char*)malloc(bl.length()); + if (!bin_) { + return -ENOBUFS; + } + int bin_len_ = bl.length(); + bl.copy(0, bin_len_, bin_); + + *bin = bin_; + *bin_len = bin_len_; + return 0; + } + catch (...) { + return -2000; + } +} + +void librgw_free_bin(char *bin) +{ + free(bin); +} diff --git a/src/test/librgw.cc b/src/test/librgw.cc new file mode 100644 index 0000000000000..76b5106577b8a --- /dev/null +++ b/src/test/librgw.cc @@ -0,0 +1,89 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "include/rados/librgw.h" + +#include "gtest/gtest.h" + +#include + +static const char SAMPLE_XML_1[] = \ +"\n\ + \n\ + foo\n\ + MrFoo\n\ + \n\ + \n\ + \n\ + \n\ + bar\n\ + display-name\n\ + \n\ + FULL_CONTROL\n\ + \n\ + \n\ +"; + +static const uint8_t VERSION1_BIN[] = { + 0x01, 0x01, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6d, + 0x63, 0x63, 0x61, 0x62, 0x65, 0x07, 0x00, 0x00, + 0x00, 0x63, 0x6d, 0x63, 0x63, 0x61, 0x62, 0x65, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6d, + 0x63, 0x63, 0x61, 0x62, 0x65, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, + 0x6d, 0x63, 0x63, 0x61, 0x62, 0x65, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, + 0x6d, 0x63, 0x63, 0x61, 0x62, 0x65, 0x0a, 0x0a +}; + +TEST(LibRGW, FromBin) { + int ret; + const char *bin = (const char*)VERSION1_BIN; + int len = sizeof(VERSION1_BIN) / sizeof(VERSION1_BIN[0]); + + char *xml = NULL; + ret = librgw_acl_bin2xml(bin, len, &xml); + ASSERT_EQ(ret, 0); +} + +TEST(LibRGW, RoundTrip) { + int ret; + char *bin = NULL; + int bin_len = 0; + ret = librgw_acl_xml2bin(SAMPLE_XML_1, &bin, &bin_len); + ASSERT_EQ(ret, 0); + + char *xml2 = NULL; + ret = librgw_acl_bin2xml(bin, bin_len, &xml2); + ASSERT_EQ(ret, 0); + + char *bin2 = NULL; + int bin_len2 = 0; + ret = librgw_acl_xml2bin(xml2, &bin2, &bin_len2); + ASSERT_EQ(ret, 0); + + // the serialized representation should be the same. + ASSERT_EQ(bin_len, bin_len2); + ASSERT_EQ(memcmp(bin, bin2, bin_len), 0); + + // Free memory + // As you can see, we ignore freeing memory on test failures + // Don't do this in your real programs! + librgw_free_bin(bin); + librgw_free_xml(xml2); + librgw_free_bin(bin2); +} -- 2.39.5