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