summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_cors_s3.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rgw/rgw_cors_s3.cc')
-rw-r--r--src/rgw/rgw_cors_s3.cc245
1 files changed, 245 insertions, 0 deletions
diff --git a/src/rgw/rgw_cors_s3.cc b/src/rgw/rgw_cors_s3.cc
new file mode 100644
index 000000000..0275156d2
--- /dev/null
+++ b/src/rgw/rgw_cors_s3.cc
@@ -0,0 +1,245 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
+ *
+ * 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 <string.h>
+#include <limits.h>
+
+#include <iostream>
+#include <map>
+
+#include "include/types.h"
+
+#include "rgw_cors_s3.h"
+#include "rgw_user.h"
+
+#define dout_context g_ceph_context
+#define dout_subsys ceph_subsys_rgw
+
+
+void RGWCORSRule_S3::to_xml(XMLFormatter& f) {
+
+ f.open_object_section("CORSRule");
+ /*ID if present*/
+ if (id.length() > 0) {
+ f.dump_string("ID", id);
+ }
+ /*AllowedMethods*/
+ if (allowed_methods & RGW_CORS_GET)
+ f.dump_string("AllowedMethod", "GET");
+ if (allowed_methods & RGW_CORS_PUT)
+ f.dump_string("AllowedMethod", "PUT");
+ if (allowed_methods & RGW_CORS_DELETE)
+ f.dump_string("AllowedMethod", "DELETE");
+ if (allowed_methods & RGW_CORS_HEAD)
+ f.dump_string("AllowedMethod", "HEAD");
+ if (allowed_methods & RGW_CORS_POST)
+ f.dump_string("AllowedMethod", "POST");
+ if (allowed_methods & RGW_CORS_COPY)
+ f.dump_string("AllowedMethod", "COPY");
+ /*AllowedOrigins*/
+ for(set<string>::iterator it = allowed_origins.begin();
+ it != allowed_origins.end();
+ ++it) {
+ string host = *it;
+ f.dump_string("AllowedOrigin", host);
+ }
+ /*AllowedHeader*/
+ for(set<string>::iterator it = allowed_hdrs.begin();
+ it != allowed_hdrs.end(); ++it) {
+ f.dump_string("AllowedHeader", *it);
+ }
+ /*MaxAgeSeconds*/
+ if (max_age != CORS_MAX_AGE_INVALID) {
+ f.dump_unsigned("MaxAgeSeconds", max_age);
+ }
+ /*ExposeHeader*/
+ for(list<string>::iterator it = exposable_hdrs.begin();
+ it != exposable_hdrs.end(); ++it) {
+ f.dump_string("ExposeHeader", *it);
+ }
+ f.close_section();
+}
+
+bool RGWCORSRule_S3::xml_end(const char *el) {
+ XMLObjIter iter = find("AllowedMethod");
+ XMLObj *obj;
+ /*Check all the allowedmethods*/
+ obj = iter.get_next();
+ if (obj) {
+ for( ; obj; obj = iter.get_next()) {
+ const char *s = obj->get_data().c_str();
+ ldpp_dout(dpp, 10) << "RGWCORSRule::xml_end, el : " << el << ", data : " << s << dendl;
+ if (strcasecmp(s, "GET") == 0) {
+ allowed_methods |= RGW_CORS_GET;
+ } else if (strcasecmp(s, "POST") == 0) {
+ allowed_methods |= RGW_CORS_POST;
+ } else if (strcasecmp(s, "DELETE") == 0) {
+ allowed_methods |= RGW_CORS_DELETE;
+ } else if (strcasecmp(s, "HEAD") == 0) {
+ allowed_methods |= RGW_CORS_HEAD;
+ } else if (strcasecmp(s, "PUT") == 0) {
+ allowed_methods |= RGW_CORS_PUT;
+ } else if (strcasecmp(s, "COPY") == 0) {
+ allowed_methods |= RGW_CORS_COPY;
+ } else {
+ return false;
+ }
+ }
+ }
+ /*Check the id's len, it should be less than 255*/
+ XMLObj *xml_id = find_first("ID");
+ if (xml_id != NULL) {
+ string data = xml_id->get_data();
+ if (data.length() > 255) {
+ ldpp_dout(dpp, 0) << "RGWCORSRule has id of length greater than 255" << dendl;
+ return false;
+ }
+ ldpp_dout(dpp, 10) << "RGWCORRule id : " << data << dendl;
+ id = data;
+ }
+ /*Check if there is atleast one AllowedOrigin*/
+ iter = find("AllowedOrigin");
+ if (!(obj = iter.get_next())) {
+ ldpp_dout(dpp, 0) << "RGWCORSRule does not have even one AllowedOrigin" << dendl;
+ return false;
+ }
+ for( ; obj; obj = iter.get_next()) {
+ ldpp_dout(dpp, 10) << "RGWCORSRule - origin : " << obj->get_data() << dendl;
+ /*Just take the hostname*/
+ string host = obj->get_data();
+ if (validate_name_string(host) != 0)
+ return false;
+ allowed_origins.insert(allowed_origins.end(), host);
+ }
+ /*Check of max_age*/
+ iter = find("MaxAgeSeconds");
+ if ((obj = iter.get_next())) {
+ char *end = NULL;
+
+ unsigned long long ull = strtoull(obj->get_data().c_str(), &end, 10);
+ if (*end != '\0') {
+ ldpp_dout(dpp, 0) << "RGWCORSRule's MaxAgeSeconds " << obj->get_data() << " is an invalid integer" << dendl;
+ return false;
+ }
+ if (ull >= 0x100000000ull) {
+ max_age = CORS_MAX_AGE_INVALID;
+ } else {
+ max_age = (uint32_t)ull;
+ }
+ ldpp_dout(dpp, 10) << "RGWCORSRule : max_age : " << max_age << dendl;
+ }
+ /*Check and update ExposeHeader*/
+ iter = find("ExposeHeader");
+ if ((obj = iter.get_next())) {
+ for(; obj; obj = iter.get_next()) {
+ ldpp_dout(dpp, 10) << "RGWCORSRule - exp_hdr : " << obj->get_data() << dendl;
+ exposable_hdrs.push_back(obj->get_data());
+ }
+ }
+ /*Check and update AllowedHeader*/
+ iter = find("AllowedHeader");
+ if ((obj = iter.get_next())) {
+ for(; obj; obj = iter.get_next()) {
+ ldpp_dout(dpp, 10) << "RGWCORSRule - allowed_hdr : " << obj->get_data() << dendl;
+ string s = obj->get_data();
+ if (validate_name_string(s) != 0)
+ return false;
+ allowed_hdrs.insert(allowed_hdrs.end(), s);
+ }
+ }
+ return true;
+}
+
+void RGWCORSConfiguration_S3::to_xml(ostream& out) {
+ XMLFormatter f;
+ f.open_object_section_in_ns("CORSConfiguration", XMLNS_AWS_S3);
+ for(list<RGWCORSRule>::iterator it = rules.begin();
+ it != rules.end(); ++it) {
+ (static_cast<RGWCORSRule_S3 &>(*it)).to_xml(f);
+ }
+ f.close_section();
+ f.flush(out);
+}
+
+bool RGWCORSConfiguration_S3::xml_end(const char *el) {
+ XMLObjIter iter = find("CORSRule");
+ RGWCORSRule_S3 *obj;
+ if (!(obj = static_cast<RGWCORSRule_S3 *>(iter.get_next()))) {
+ ldpp_dout(dpp, 0) << "CORSConfiguration should have atleast one CORSRule" << dendl;
+ return false;
+ }
+ for(; obj; obj = static_cast<RGWCORSRule_S3 *>(iter.get_next())) {
+ rules.push_back(*obj);
+ }
+ return true;
+}
+
+class CORSRuleID_S3 : public XMLObj {
+ public:
+ CORSRuleID_S3() {}
+ ~CORSRuleID_S3() override {}
+};
+
+class CORSRuleAllowedOrigin_S3 : public XMLObj {
+ public:
+ CORSRuleAllowedOrigin_S3() {}
+ ~CORSRuleAllowedOrigin_S3() override {}
+};
+
+class CORSRuleAllowedMethod_S3 : public XMLObj {
+ public:
+ CORSRuleAllowedMethod_S3() {}
+ ~CORSRuleAllowedMethod_S3() override {}
+};
+
+class CORSRuleAllowedHeader_S3 : public XMLObj {
+ public:
+ CORSRuleAllowedHeader_S3() {}
+ ~CORSRuleAllowedHeader_S3() override {}
+};
+
+class CORSRuleMaxAgeSeconds_S3 : public XMLObj {
+ public:
+ CORSRuleMaxAgeSeconds_S3() {}
+ ~CORSRuleMaxAgeSeconds_S3() override {}
+};
+
+class CORSRuleExposeHeader_S3 : public XMLObj {
+ public:
+ CORSRuleExposeHeader_S3() {}
+ ~CORSRuleExposeHeader_S3() override {}
+};
+
+XMLObj *RGWCORSXMLParser_S3::alloc_obj(const char *el) {
+ if (strcmp(el, "CORSConfiguration") == 0) {
+ return new RGWCORSConfiguration_S3(dpp);
+ } else if (strcmp(el, "CORSRule") == 0) {
+ return new RGWCORSRule_S3(dpp);
+ } else if (strcmp(el, "ID") == 0) {
+ return new CORSRuleID_S3;
+ } else if (strcmp(el, "AllowedOrigin") == 0) {
+ return new CORSRuleAllowedOrigin_S3;
+ } else if (strcmp(el, "AllowedMethod") == 0) {
+ return new CORSRuleAllowedMethod_S3;
+ } else if (strcmp(el, "AllowedHeader") == 0) {
+ return new CORSRuleAllowedHeader_S3;
+ } else if (strcmp(el, "MaxAgeSeconds") == 0) {
+ return new CORSRuleMaxAgeSeconds_S3;
+ } else if (strcmp(el, "ExposeHeader") == 0) {
+ return new CORSRuleExposeHeader_S3;
+ }
+ return NULL;
+}
+