Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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