]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_cors_s3.cc
import ceph pacific 16.2.5
[ceph.git] / ceph / src / rgw / rgw_cors_s3.cc
CommitLineData
7c673cae 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
9f95a23c 2// vim: ts=8 sw=2 smarttab ft=cpp
11fdf7f2 3
7c673cae
FG
4/*
5 * Ceph - scalable distributed file system
6 *
7 * Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
8 *
9 * This is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License version 2.1, as published by the Free Software
12 * Foundation. See file COPYING.
13 *
14 */
11fdf7f2 15
7c673cae
FG
16#include <string.h>
17#include <limits.h>
18
19#include <iostream>
20#include <map>
21
22#include "include/types.h"
23
24#include "rgw_cors_s3.h"
25#include "rgw_user.h"
26
27#define dout_context g_ceph_context
28#define dout_subsys ceph_subsys_rgw
29
7c673cae
FG
30
31void RGWCORSRule_S3::to_xml(XMLFormatter& f) {
32
33 f.open_object_section("CORSRule");
34 /*ID if present*/
35 if (id.length() > 0) {
36 f.dump_string("ID", id);
37 }
38 /*AllowedMethods*/
39 if (allowed_methods & RGW_CORS_GET)
40 f.dump_string("AllowedMethod", "GET");
41 if (allowed_methods & RGW_CORS_PUT)
42 f.dump_string("AllowedMethod", "PUT");
43 if (allowed_methods & RGW_CORS_DELETE)
44 f.dump_string("AllowedMethod", "DELETE");
45 if (allowed_methods & RGW_CORS_HEAD)
46 f.dump_string("AllowedMethod", "HEAD");
47 if (allowed_methods & RGW_CORS_POST)
48 f.dump_string("AllowedMethod", "POST");
49 if (allowed_methods & RGW_CORS_COPY)
50 f.dump_string("AllowedMethod", "COPY");
51 /*AllowedOrigins*/
52 for(set<string>::iterator it = allowed_origins.begin();
53 it != allowed_origins.end();
54 ++it) {
55 string host = *it;
56 f.dump_string("AllowedOrigin", host);
57 }
58 /*AllowedHeader*/
59 for(set<string>::iterator it = allowed_hdrs.begin();
60 it != allowed_hdrs.end(); ++it) {
61 f.dump_string("AllowedHeader", *it);
62 }
63 /*MaxAgeSeconds*/
64 if (max_age != CORS_MAX_AGE_INVALID) {
65 f.dump_unsigned("MaxAgeSeconds", max_age);
66 }
67 /*ExposeHeader*/
68 for(list<string>::iterator it = exposable_hdrs.begin();
69 it != exposable_hdrs.end(); ++it) {
70 f.dump_string("ExposeHeader", *it);
71 }
72 f.close_section();
73}
74
75bool RGWCORSRule_S3::xml_end(const char *el) {
76 XMLObjIter iter = find("AllowedMethod");
77 XMLObj *obj;
78 /*Check all the allowedmethods*/
79 obj = iter.get_next();
80 if (obj) {
81 for( ; obj; obj = iter.get_next()) {
82 const char *s = obj->get_data().c_str();
b3b6e05e 83 ldpp_dout(dpp, 10) << "RGWCORSRule::xml_end, el : " << el << ", data : " << s << dendl;
7c673cae
FG
84 if (strcasecmp(s, "GET") == 0) {
85 allowed_methods |= RGW_CORS_GET;
86 } else if (strcasecmp(s, "POST") == 0) {
87 allowed_methods |= RGW_CORS_POST;
88 } else if (strcasecmp(s, "DELETE") == 0) {
89 allowed_methods |= RGW_CORS_DELETE;
90 } else if (strcasecmp(s, "HEAD") == 0) {
91 allowed_methods |= RGW_CORS_HEAD;
92 } else if (strcasecmp(s, "PUT") == 0) {
93 allowed_methods |= RGW_CORS_PUT;
94 } else if (strcasecmp(s, "COPY") == 0) {
95 allowed_methods |= RGW_CORS_COPY;
96 } else {
97 return false;
98 }
99 }
100 }
101 /*Check the id's len, it should be less than 255*/
102 XMLObj *xml_id = find_first("ID");
103 if (xml_id != NULL) {
104 string data = xml_id->get_data();
105 if (data.length() > 255) {
b3b6e05e 106 ldpp_dout(dpp, 0) << "RGWCORSRule has id of length greater than 255" << dendl;
7c673cae
FG
107 return false;
108 }
b3b6e05e 109 ldpp_dout(dpp, 10) << "RGWCORRule id : " << data << dendl;
7c673cae
FG
110 id = data;
111 }
112 /*Check if there is atleast one AllowedOrigin*/
113 iter = find("AllowedOrigin");
114 if (!(obj = iter.get_next())) {
b3b6e05e 115 ldpp_dout(dpp, 0) << "RGWCORSRule does not have even one AllowedOrigin" << dendl;
7c673cae
FG
116 return false;
117 }
118 for( ; obj; obj = iter.get_next()) {
b3b6e05e 119 ldpp_dout(dpp, 10) << "RGWCORSRule - origin : " << obj->get_data() << dendl;
7c673cae
FG
120 /*Just take the hostname*/
121 string host = obj->get_data();
122 if (validate_name_string(host) != 0)
123 return false;
124 allowed_origins.insert(allowed_origins.end(), host);
125 }
126 /*Check of max_age*/
127 iter = find("MaxAgeSeconds");
128 if ((obj = iter.get_next())) {
129 char *end = NULL;
130
131 unsigned long long ull = strtoull(obj->get_data().c_str(), &end, 10);
11fdf7f2 132 if (*end != '\0') {
b3b6e05e 133 ldpp_dout(dpp, 0) << "RGWCORSRule's MaxAgeSeconds " << obj->get_data() << " is an invalid integer" << dendl;
11fdf7f2
TL
134 return false;
135 }
7c673cae
FG
136 if (ull >= 0x100000000ull) {
137 max_age = CORS_MAX_AGE_INVALID;
138 } else {
139 max_age = (uint32_t)ull;
140 }
b3b6e05e 141 ldpp_dout(dpp, 10) << "RGWCORSRule : max_age : " << max_age << dendl;
7c673cae
FG
142 }
143 /*Check and update ExposeHeader*/
144 iter = find("ExposeHeader");
145 if ((obj = iter.get_next())) {
146 for(; obj; obj = iter.get_next()) {
b3b6e05e 147 ldpp_dout(dpp, 10) << "RGWCORSRule - exp_hdr : " << obj->get_data() << dendl;
7c673cae
FG
148 exposable_hdrs.push_back(obj->get_data());
149 }
150 }
151 /*Check and update AllowedHeader*/
152 iter = find("AllowedHeader");
153 if ((obj = iter.get_next())) {
154 for(; obj; obj = iter.get_next()) {
b3b6e05e 155 ldpp_dout(dpp, 10) << "RGWCORSRule - allowed_hdr : " << obj->get_data() << dendl;
7c673cae
FG
156 string s = obj->get_data();
157 if (validate_name_string(s) != 0)
158 return false;
159 allowed_hdrs.insert(allowed_hdrs.end(), s);
160 }
161 }
162 return true;
163}
164
165void RGWCORSConfiguration_S3::to_xml(ostream& out) {
166 XMLFormatter f;
167 f.open_object_section_in_ns("CORSConfiguration", XMLNS_AWS_S3);
168 for(list<RGWCORSRule>::iterator it = rules.begin();
169 it != rules.end(); ++it) {
170 (static_cast<RGWCORSRule_S3 &>(*it)).to_xml(f);
171 }
172 f.close_section();
173 f.flush(out);
174}
175
176bool RGWCORSConfiguration_S3::xml_end(const char *el) {
177 XMLObjIter iter = find("CORSRule");
178 RGWCORSRule_S3 *obj;
179 if (!(obj = static_cast<RGWCORSRule_S3 *>(iter.get_next()))) {
b3b6e05e 180 ldpp_dout(dpp, 0) << "CORSConfiguration should have atleast one CORSRule" << dendl;
7c673cae
FG
181 return false;
182 }
183 for(; obj; obj = static_cast<RGWCORSRule_S3 *>(iter.get_next())) {
184 rules.push_back(*obj);
185 }
186 return true;
187}
188
189class CORSRuleID_S3 : public XMLObj {
190 public:
191 CORSRuleID_S3() {}
192 ~CORSRuleID_S3() override {}
193};
194
195class CORSRuleAllowedOrigin_S3 : public XMLObj {
196 public:
197 CORSRuleAllowedOrigin_S3() {}
198 ~CORSRuleAllowedOrigin_S3() override {}
199};
200
201class CORSRuleAllowedMethod_S3 : public XMLObj {
202 public:
203 CORSRuleAllowedMethod_S3() {}
204 ~CORSRuleAllowedMethod_S3() override {}
205};
206
207class CORSRuleAllowedHeader_S3 : public XMLObj {
208 public:
209 CORSRuleAllowedHeader_S3() {}
210 ~CORSRuleAllowedHeader_S3() override {}
211};
212
213class CORSRuleMaxAgeSeconds_S3 : public XMLObj {
214 public:
215 CORSRuleMaxAgeSeconds_S3() {}
216 ~CORSRuleMaxAgeSeconds_S3() override {}
217};
218
219class CORSRuleExposeHeader_S3 : public XMLObj {
220 public:
221 CORSRuleExposeHeader_S3() {}
222 ~CORSRuleExposeHeader_S3() override {}
223};
224
225XMLObj *RGWCORSXMLParser_S3::alloc_obj(const char *el) {
226 if (strcmp(el, "CORSConfiguration") == 0) {
b3b6e05e 227 return new RGWCORSConfiguration_S3(dpp);
7c673cae 228 } else if (strcmp(el, "CORSRule") == 0) {
b3b6e05e 229 return new RGWCORSRule_S3(dpp);
7c673cae
FG
230 } else if (strcmp(el, "ID") == 0) {
231 return new CORSRuleID_S3;
232 } else if (strcmp(el, "AllowedOrigin") == 0) {
233 return new CORSRuleAllowedOrigin_S3;
234 } else if (strcmp(el, "AllowedMethod") == 0) {
235 return new CORSRuleAllowedMethod_S3;
236 } else if (strcmp(el, "AllowedHeader") == 0) {
237 return new CORSRuleAllowedHeader_S3;
238 } else if (strcmp(el, "MaxAgeSeconds") == 0) {
239 return new CORSRuleMaxAgeSeconds_S3;
240 } else if (strcmp(el, "ExposeHeader") == 0) {
241 return new CORSRuleExposeHeader_S3;
242 }
243 return NULL;
244}
245