1 /*
2 * Copyright (C) 2020-2021 Bareos GmbH & Co. KG
3 * Copyright (C) 2010 SCALITY SA. All rights reserved.
4 * http://www.scality.com
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY SCALITY SA ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL SCALITY SA OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * The views and conclusions contained in the software and documentation
30 * are those of the authors and should not be interpreted as representing
31 * official policies, either expressed or implied, of SCALITY SA.
32 *
33 * https://github.com/scality/Droplet
34 */
35 #include "dropletp.h"
36
37 //#define DPRINTF(fmt,...) fprintf(stderr, fmt, ##__VA_ARGS__)
38 #define DPRINTF(fmt, ...)
39
dpl_req_free(dpl_req_t * req)40 void dpl_req_free(dpl_req_t* req)
41 {
42 if (NULL != req->host) free(req->host);
43
44 if (NULL != req->port) free(req->port);
45
46 if (NULL != req->bucket) free(req->bucket);
47
48 if (NULL != req->resource) free(req->resource);
49
50 if (NULL != req->subresource) free(req->subresource);
51
52 if (NULL != req->cache_control) free(req->cache_control);
53
54 if (NULL != req->content_disposition) free(req->content_disposition);
55
56 if (NULL != req->content_encoding) free(req->content_encoding);
57
58 if (NULL != req->content_type) free(req->content_type);
59
60 if (NULL != req->metadata) dpl_dict_free(req->metadata);
61
62 if (NULL != req->src_bucket) free(req->src_bucket);
63
64 if (NULL != req->src_resource) free(req->src_resource);
65
66 if (NULL != req->src_subresource) free(req->src_subresource);
67
68 free(req);
69 }
70
dpl_req_new(dpl_ctx_t * ctx)71 dpl_req_t* dpl_req_new(dpl_ctx_t* ctx)
72 {
73 dpl_req_t* req = NULL;
74
75 req = malloc(sizeof(*req));
76 if (NULL == req) goto bad;
77
78 memset(req, 0, sizeof(*req));
79
80 req->ctx = ctx;
81
82 req->metadata = dpl_dict_new(13);
83 if (NULL == req->metadata) goto bad;
84
85 // virtual hosting is prefered since it "disperses" connections
86 req->behavior_flags = DPL_BEHAVIOR_KEEP_ALIVE | DPL_BEHAVIOR_VIRTUAL_HOSTING;
87
88 return req;
89
90 bad:
91
92 if (NULL != req) dpl_req_free(req);
93
94 return NULL;
95 }
96
dpl_req_set_host(dpl_req_t * req,const char * host)97 dpl_status_t dpl_req_set_host(dpl_req_t* req, const char* host)
98 {
99 char* nstr;
100
101 nstr = strdup(host);
102 if (NULL == nstr) return DPL_ENOMEM;
103
104 if (NULL != req->host) free(req->host);
105
106 req->host = nstr;
107
108 return DPL_SUCCESS;
109 }
110
dpl_req_set_port(dpl_req_t * req,const char * port)111 dpl_status_t dpl_req_set_port(dpl_req_t* req, const char* port)
112 {
113 char* nstr;
114
115 nstr = strdup(port);
116 if (NULL == nstr) return DPL_ENOMEM;
117
118 if (NULL != req->port) free(req->port);
119
120 req->port = nstr;
121
122 return DPL_SUCCESS;
123 }
124
dpl_req_set_method(dpl_req_t * req,dpl_method_t method)125 void dpl_req_set_method(dpl_req_t* req, dpl_method_t method)
126 {
127 req->method = method;
128 }
129
dpl_req_set_bucket(dpl_req_t * req,const char * bucket)130 dpl_status_t dpl_req_set_bucket(dpl_req_t* req, const char* bucket)
131 {
132 char* nstr;
133
134 nstr = strdup(bucket);
135 if (NULL == nstr) return DPL_ENOMEM;
136
137 if (NULL != req->bucket) free(req->bucket);
138
139 req->bucket = nstr;
140
141 return DPL_SUCCESS;
142 }
143
dpl_req_set_resource(dpl_req_t * req,const char * resource)144 dpl_status_t dpl_req_set_resource(dpl_req_t* req, const char* resource)
145 {
146 char* nstr;
147 char npath[DPL_MAXPATHLEN];
148
149 if (resource == NULL || *resource == '\0' || !strcmp(resource, "/")) {
150 if (!strcmp(req->ctx->base_path, "/")) {
151 if (!req->ctx->preserve_root_path)
152 npath[0] = '\0';
153 else
154 strncpy(npath, resource, sizeof(npath));
155 } else {
156 if (!req->ctx->preserve_root_path)
157 strncpy(npath, req->ctx->base_path, sizeof(npath));
158 else {
159 snprintf(npath, sizeof(npath), "%s%s", req->ctx->base_path, resource);
160 }
161 }
162 } else {
163 if (!strcmp(req->ctx->base_path, "/"))
164 snprintf(npath, sizeof(npath), "%s", resource);
165 else
166 snprintf(npath, sizeof(npath), "%s/%s", req->ctx->base_path, resource);
167 }
168
169 nstr = strdup(npath);
170 if (NULL == nstr) return DPL_ENOMEM;
171
172 if (NULL != req->resource) free(req->resource);
173
174 req->resource = nstr;
175 return DPL_SUCCESS;
176 }
177
dpl_req_set_subresource(dpl_req_t * req,const char * subresource)178 dpl_status_t dpl_req_set_subresource(dpl_req_t* req, const char* subresource)
179 {
180 char* nstr;
181
182 nstr = strdup(subresource);
183 if (NULL == nstr) return DPL_ENOMEM;
184
185 if (NULL != req->subresource) free(req->subresource);
186
187 req->subresource = nstr;
188
189 return DPL_SUCCESS;
190 }
191
dpl_req_add_subresource(dpl_req_t * req,const char * subresource)192 dpl_status_t dpl_req_add_subresource(dpl_req_t* req, const char* subresource)
193 {
194 char* tmp = NULL;
195
196 if (!req->subresource) return dpl_req_set_subresource(req, subresource);
197
198 tmp = realloc(req->subresource,
199 strlen(req->subresource) + strlen(subresource) + 2);
200 if (!tmp) return DPL_ENOMEM;
201
202 tmp = strcat(tmp, ";");
203 tmp = strcat(tmp, subresource);
204 req->subresource = tmp;
205
206 return DPL_SUCCESS;
207 }
208
dpl_req_add_behavior(dpl_req_t * req,unsigned int flags)209 void dpl_req_add_behavior(dpl_req_t* req, unsigned int flags)
210 {
211 req->behavior_flags |= flags;
212 }
213
dpl_req_rm_behavior(dpl_req_t * req,unsigned int flags)214 void dpl_req_rm_behavior(dpl_req_t* req, unsigned int flags)
215 {
216 req->behavior_flags &= ~flags;
217 }
218
dpl_req_set_location_constraint(dpl_req_t * req,dpl_location_constraint_t location_constraint)219 void dpl_req_set_location_constraint(
220 dpl_req_t* req,
221 dpl_location_constraint_t location_constraint)
222 {
223 req->location_constraint = location_constraint;
224 }
225
dpl_req_set_canned_acl(dpl_req_t * req,dpl_canned_acl_t canned_acl)226 void dpl_req_set_canned_acl(dpl_req_t* req, dpl_canned_acl_t canned_acl)
227 {
228 req->canned_acl = canned_acl;
229 }
230
dpl_req_set_storage_class(dpl_req_t * req,dpl_storage_class_t storage_class)231 void dpl_req_set_storage_class(dpl_req_t* req,
232 dpl_storage_class_t storage_class)
233 {
234 req->storage_class = storage_class;
235 }
236
dpl_req_set_condition(dpl_req_t * req,const dpl_condition_t * condition)237 void dpl_req_set_condition(dpl_req_t* req, const dpl_condition_t* condition)
238 {
239 req->condition = *condition;
240 }
241
dpl_req_set_cache_control(dpl_req_t * req,const char * cache_control)242 dpl_status_t dpl_req_set_cache_control(dpl_req_t* req,
243 const char* cache_control)
244 {
245 char* nstr;
246
247 nstr = strdup(cache_control);
248 if (NULL == nstr) return DPL_ENOMEM;
249
250 if (NULL != req->cache_control) free(req->cache_control);
251
252 req->cache_control = nstr;
253
254 return DPL_SUCCESS;
255 }
256
dpl_req_set_content_disposition(dpl_req_t * req,const char * content_disposition)257 dpl_status_t dpl_req_set_content_disposition(dpl_req_t* req,
258 const char* content_disposition)
259 {
260 char* nstr;
261
262 nstr = strdup(content_disposition);
263 if (NULL == nstr) return DPL_ENOMEM;
264
265 if (NULL != req->content_disposition) free(req->content_disposition);
266
267 req->content_disposition = nstr;
268
269 return DPL_SUCCESS;
270 }
271
dpl_req_set_content_encoding(dpl_req_t * req,const char * content_encoding)272 dpl_status_t dpl_req_set_content_encoding(dpl_req_t* req,
273 const char* content_encoding)
274 {
275 char* nstr;
276
277 nstr = strdup(content_encoding);
278 if (NULL == nstr) return DPL_ENOMEM;
279
280 if (NULL != req->content_encoding) free(req->content_encoding);
281
282 req->content_encoding = nstr;
283
284 return DPL_SUCCESS;
285 }
286
dpl_req_set_data(dpl_req_t * req,const char * data_buf,u_int data_len)287 void dpl_req_set_data(dpl_req_t* req, const char* data_buf, u_int data_len)
288 {
289 req->data_buf = data_buf;
290 req->data_len = data_len;
291 req->data_enabled = 1;
292 }
293
dpl_req_add_metadatum(dpl_req_t * req,const char * key,const char * value)294 dpl_status_t dpl_req_add_metadatum(dpl_req_t* req,
295 const char* key,
296 const char* value)
297 {
298 return dpl_dict_add(req->metadata, key, value, 0);
299 }
300
dpl_req_add_metadata(dpl_req_t * req,const dpl_dict_t * metadata)301 dpl_status_t dpl_req_add_metadata(dpl_req_t* req, const dpl_dict_t* metadata)
302 {
303 int ret;
304
305 ret = dpl_dict_copy(req->metadata, metadata);
306 if (DPL_SUCCESS != ret) { return DPL_FAILURE; }
307
308 return DPL_SUCCESS;
309 }
310
dpl_req_set_content_type(dpl_req_t * req,const char * content_type)311 dpl_status_t dpl_req_set_content_type(dpl_req_t* req, const char* content_type)
312 {
313 char* nstr;
314
315 nstr = strdup(content_type);
316 if (NULL == nstr) return DPL_ENOMEM;
317
318 if (NULL != req->content_type) free(req->content_type);
319
320 req->content_type = nstr;
321
322 return DPL_SUCCESS;
323 }
324
dpl_req_set_object_type(dpl_req_t * req,dpl_ftype_t object_type)325 dpl_status_t dpl_req_set_object_type(dpl_req_t* req, dpl_ftype_t object_type)
326 {
327 req->object_type = object_type;
328
329 return DPL_SUCCESS;
330 }
331
dpl_req_add_range(dpl_req_t * req,uint64_t start,uint64_t end)332 dpl_status_t dpl_req_add_range(dpl_req_t* req, uint64_t start, uint64_t end)
333 {
334 req->range.start = start;
335 req->range.end = end;
336 req->range_enabled = 1;
337
338 return DPL_SUCCESS;
339 }
340
dpl_req_set_expires(dpl_req_t * req,time_t expires)341 void dpl_req_set_expires(dpl_req_t* req, time_t expires)
342 {
343 req->expires = expires;
344 }
345
dpl_req_set_src_bucket(dpl_req_t * req,const char * src_bucket)346 dpl_status_t dpl_req_set_src_bucket(dpl_req_t* req, const char* src_bucket)
347 {
348 char* nstr;
349
350 nstr = strdup(src_bucket);
351 if (NULL == nstr) return DPL_ENOMEM;
352
353 if (NULL != req->src_bucket) free(req->src_bucket);
354
355 req->src_bucket = nstr;
356
357 return DPL_SUCCESS;
358 }
359
dpl_req_set_src_resource_ext(dpl_req_t * req,const char * src_resource,int add_base_path)360 dpl_status_t dpl_req_set_src_resource_ext(dpl_req_t* req,
361 const char* src_resource,
362 int add_base_path)
363 {
364 char* nstr;
365 char npath[DPL_MAXPATHLEN];
366
367 if (add_base_path) {
368 if (!strcmp(req->ctx->base_path, "/"))
369 snprintf(npath, sizeof(npath), "%s", src_resource);
370 else
371 snprintf(npath, sizeof(npath), "%s/%s", req->ctx->base_path,
372 src_resource);
373 } else
374 snprintf(npath, sizeof(npath), "%s", src_resource);
375
376 nstr = strdup(npath);
377 if (NULL == nstr) return DPL_ENOMEM;
378
379 if (NULL != req->src_resource) free(req->src_resource);
380
381 req->src_resource = nstr;
382
383 return DPL_SUCCESS;
384 }
385
dpl_req_set_src_resource(dpl_req_t * req,const char * src_resource)386 dpl_status_t dpl_req_set_src_resource(dpl_req_t* req, const char* src_resource)
387 {
388 return dpl_req_set_src_resource_ext(req, src_resource, 1);
389 }
390
dpl_req_set_src_subresource(dpl_req_t * req,const char * src_subresource)391 dpl_status_t dpl_req_set_src_subresource(dpl_req_t* req,
392 const char* src_subresource)
393 {
394 char* nstr;
395 nstr = strdup(src_subresource);
396 if (NULL == nstr) return DPL_ENOMEM;
397
398 if (NULL != req->src_subresource) free(req->src_subresource);
399
400 req->src_subresource = nstr;
401
402 return DPL_SUCCESS;
403 }
404
dpl_req_set_copy_directive(dpl_req_t * req,dpl_copy_directive_t copy_directive)405 void dpl_req_set_copy_directive(dpl_req_t* req,
406 dpl_copy_directive_t copy_directive)
407 {
408 req->copy_directive = copy_directive;
409 }
410
dpl_req_set_copy_source_condition(dpl_req_t * req,const dpl_condition_t * condition)411 void dpl_req_set_copy_source_condition(dpl_req_t* req,
412 const dpl_condition_t* condition)
413 {
414 req->copy_source_condition = *condition;
415 }
416