dpl_status_t dpl_cdmi_put_buffered(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, dpl_ftype_t object_type, const dpl_dict_t *metadata, const dpl_sysmd_t *sysmd, unsigned int data_len, dpl_conn_t **connp) { char *host; int ret, ret2; dpl_conn_t *conn = NULL; char header[1024]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_chunk_t chunk; req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_PUT); if (NULL != bucket) { ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } chunk.buf = NULL; chunk.len = data_len; dpl_req_set_chunk(req, &chunk); //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); dpl_req_add_behavior(req, DPL_BEHAVIOR_HTTP_COMPAT); dpl_req_set_object_type(req, object_type); dpl_req_add_behavior(req, DPL_BEHAVIOR_EXPECT); if (NULL != metadata) { ret2 = dpl_req_add_metadata(req, metadata); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } ret2 = dpl_cdmi_req_build(req, &headers_request, NULL, NULL); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } host = dpl_dict_get_value(headers_request, "Host"); if (NULL == host) { ret = DPL_FAILURE; goto end; } conn = dpl_conn_open_host(ctx, host, ctx->port); if (NULL == conn) { ret = DPL_FAILURE; goto end; } //bucket emulation ret2 = dpl_dict_add(headers_request, "X-Scality-Bucket", bucket, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPLERR(1, "writev failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } ret2 = dpl_read_http_reply(conn, 1, NULL, NULL, &headers_reply); if (DPL_SUCCESS != ret2) { if (DPL_ENOENT == ret2) { ret = DPL_ENOENT; goto end; } else { DPLERR(0, "read http answer failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } } else { if (NULL != headers_reply) //possible if continue succeeded connection_close = dpl_connection_close(ctx, headers_reply); } (void) dpl_log_event(ctx, "DATA", "IN", data_len); if (NULL != connp) { *connp = conn; conn = NULL; //consume it } ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPRINTF("ret=%d\n", ret); return ret; }
dpl_status_t dpl_cdmi_delete(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, dpl_ftype_t object_type) { char *host; int ret, ret2; dpl_conn_t *conn = NULL; char header[1024]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_DELETE); ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); dpl_req_add_behavior(req, DPL_BEHAVIOR_HTTP_COMPAT); //build request ret2 = dpl_cdmi_req_build(req, &headers_request, NULL, NULL); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } host = dpl_dict_get_value(headers_request, "Host"); if (NULL == host) { ret = DPL_FAILURE; goto end; } conn = dpl_conn_open_host(ctx, host, ctx->port); if (NULL == conn) { ret = DPL_FAILURE; goto end; } //bucket emulation ret2 = dpl_dict_add(headers_request, "X-Scality-Bucket", bucket, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPLERR(1, "writev failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } ret2 = dpl_read_http_reply(conn, 1, NULL, NULL, &headers_reply); if (DPL_SUCCESS != ret2) { if (DPL_ENOENT == ret2) { ret = DPL_ENOENT; goto end; } else { DPLERR(0, "read http answer failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } } else { connection_close = dpl_connection_close(ctx, headers_reply); } (void) dpl_log_event(ctx, "REQUEST", "DELETE", 0); ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPRINTF("ret=%d\n", ret); return ret; }
dpl_status_t dpl_cdmi_list_bucket(dpl_ctx_t *ctx, const char *bucket, const char *prefix, const char *delimiter, dpl_vec_t **objectsp, dpl_vec_t **common_prefixesp) { char *host; int ret, ret2; dpl_conn_t *conn = NULL; char header[1024]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; char *data_buf = NULL; u_int data_len; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_vec_t *common_prefixes = NULL; dpl_vec_t *objects = NULL; req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_GET); ret2 = dpl_req_set_resource(req, NULL != prefix ? prefix : "/"); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); dpl_req_set_object_type(req, DPL_FTYPE_DIR); //build request ret2 = dpl_cdmi_req_build(req, &headers_request, NULL, NULL); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } host = dpl_dict_get_value(headers_request, "Host"); if (NULL == host) { ret = DPL_FAILURE; goto end; } conn = dpl_conn_open_host(ctx, host, ctx->port); if (NULL == conn) { ret = DPL_FAILURE; goto end; } //bucket emulation ret2 = dpl_dict_add(headers_request, "X-Scality-Bucket", bucket, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPLERR(1, "writev failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } ret2 = dpl_read_http_reply(conn, 1, &data_buf, &data_len, &headers_reply); if (DPL_SUCCESS != ret2) { if (DPL_ENOENT == ret2) { ret = DPL_ENOENT; goto end; } else { DPLERR(0, "read http answer failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } } else { connection_close = dpl_connection_close(ctx, headers_reply); } (void) dpl_log_event(ctx, "DATA", "OUT", data_len); objects = dpl_vec_new(2, 2); if (NULL == objects) { ret = DPL_FAILURE; goto end; } common_prefixes = dpl_vec_new(2, 2); if (NULL == common_prefixes) { ret = DPL_FAILURE; goto end; } ret = dpl_cdmi_parse_list_bucket(ctx, data_buf, data_len, prefix, objects, common_prefixes); if (DPL_SUCCESS != ret) { ret = DPL_FAILURE; goto end; } if (NULL != objectsp) { *objectsp = objects; objects = NULL; //consume it } if (NULL != common_prefixesp) { *common_prefixesp = common_prefixes; common_prefixes = NULL; //consume it } ret = DPL_SUCCESS; end: if (NULL != objects) dpl_vec_objects_free(objects); if (NULL != common_prefixes) dpl_vec_common_prefixes_free(common_prefixes); if (NULL != data_buf) free(data_buf); if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPRINTF("ret=%d\n", ret); return ret; }
dpl_status_t dpl_sproxyd_put_internal(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, const dpl_option_t *option, dpl_ftype_t object_type, const dpl_condition_t *condition, const dpl_range_t *range, const dpl_dict_t *metadata, const dpl_sysmd_t *sysmd, const char *data_buf, unsigned int data_len, int mdonly, char **locationp) { int ret, ret2; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_sproxyd_req_mask_t req_mask = 0u; dpl_dict_t *query_params = NULL; uint32_t force_version = -1; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_PUT); ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } dpl_req_set_object_type(req, object_type); if (NULL != condition) { dpl_req_set_condition(req, condition); } if (option) { if (option->mask & DPL_OPTION_CONSISTENT) req_mask |= DPL_SPROXYD_REQ_CONSISTENT; if (option->mask & DPL_OPTION_EXPECT_VERSION) { req_mask = DPL_SPROXYD_REQ_EXPECT_VERSION; query_params = dpl_dict_new(13); if (NULL == query_params) { ret = DPL_ENOMEM; goto end; } ret2 = dpl_dict_add(query_params, "version", option->expect_version, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (option->mask & DPL_OPTION_FORCE_VERSION) { req_mask = DPL_SPROXYD_REQ_FORCE_VERSION; force_version = strtoul(option->force_version, NULL, 0); } } if (mdonly) { req_mask |= DPL_SPROXYD_REQ_MD_ONLY; } else { dpl_req_set_data(req, data_buf, data_len); } dpl_req_add_behavior(req, DPL_BEHAVIOR_MD5); if (NULL != metadata) { ret2 = dpl_req_add_metadata(req, metadata); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } //build request ret2 = dpl_sproxyd_req_build(req, req_mask, force_version, &headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); ret2 = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, query_params, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; //buffer iov[n_iov].iov_base = (void *)data_buf; iov[n_iov].iov_len = data_len; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; ret = ret2; goto end; } ret2 = dpl_read_http_reply(conn, 1, NULL, NULL, &headers_reply, &connection_close); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != query_params) dpl_dict_free(query_params); if (NULL != req) dpl_req_free(req); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
dpl_status_t dpl_cdmi_get_buffered(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, dpl_ftype_t object_type, const dpl_condition_t *condition, dpl_header_func_t header_func, dpl_buffer_func_t buffer_func, void *cb_arg) { char *host; int ret, ret2; dpl_conn_t *conn = NULL; char header[1024]; u_int header_len; struct iovec iov[10]; int n_iov = 0; dpl_dict_t *headers_request = NULL; dpl_req_t *req = NULL; struct get_conven gc; memset(&gc, 0, sizeof (gc)); gc.header_func = header_func; gc.buffer_func = buffer_func; gc.cb_arg = cb_arg; req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_GET); if (NULL != bucket) { ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (NULL != condition) { dpl_req_set_condition(req, condition); } //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); dpl_req_add_behavior(req, DPL_BEHAVIOR_HTTP_COMPAT); //build request ret2 = dpl_cdmi_req_build(req, &headers_request, NULL, NULL); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } host = dpl_dict_get_value(headers_request, "Host"); if (NULL == host) { ret = DPL_FAILURE; goto end; } conn = dpl_conn_open_host(ctx, host, ctx->port); if (NULL == conn) { ret = DPL_FAILURE; goto end; } //bucket emulation ret2 = dpl_dict_add(headers_request, "X-Scality-Bucket", bucket, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPLERR(1, "writev failed"); gc.connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } ret2 = dpl_read_http_reply_buffered(conn, 1, cb_get_header, cb_get_buffer, &gc); if (DPL_SUCCESS != ret2) { if (DPL_ENOENT == ret2) { ret = DPL_ENOENT; goto end; } else { DPLERR(0, "read http answer failed"); gc.connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } } //caller is responsible for logging the event ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == gc.connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPRINTF("ret=%d\n", ret); return ret; }
dpl_status_t dpl_s3_stream_multipart_put(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *uploadid, unsigned int partnb, char *buf, unsigned int len, const char **etagp) { dpl_status_t ret; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_s3_req_mask_t req_mask = 0u; dpl_req_t *req = NULL; char subresource[ 11 /* for 'partNumber=' */ + 18 /* max len for %lu */ + 10 /* for 'uploadId=' */ + strlen(uploadid)]; snprintf(subresource, sizeof(subresource), "partNumber=%u&uploadId=%s", partnb, uploadid); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_PUT); if (NULL == bucket) { ret = DPL_EINVAL; goto end; } ret = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret) goto end; ret = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret) goto end; ret = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret) goto end; dpl_req_set_data(req, buf, len); dpl_req_add_behavior(req, DPL_BEHAVIOR_MD5); ret = dpl_s3_req_build(req, req_mask, &headers_request); if (DPL_SUCCESS != ret) goto end; ret = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret) goto end; ret = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret) goto end; ret = dpl_s3_add_authorization_to_headers(req, headers_request, NULL, NULL); if (DPL_SUCCESS != ret) goto end; ret = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret) goto end; iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; //buffer iov[n_iov].iov_base = (void *)buf; iov[n_iov].iov_len = len; n_iov++; ret = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; goto end; } ret = dpl_read_http_reply(conn, 1, NULL, NULL, &headers_reply, &connection_close); if (DPL_SUCCESS != ret) goto end; if (etagp) { /* * Etag of the part is returned as a header, as a string value. * Thus, it should be surrounded by double-quotes that we need * to remove */ dpl_dict_var_t *var = NULL; const char *ro_etag = NULL; const char *start_etag = NULL; const char *end_etag = NULL; ret = dpl_dict_get_lowered(headers_reply, "Etag", &var); if (ret != DPL_SUCCESS || var == NULL) { ret = DPL_FAILURE; goto end; } assert(var->val->type == DPL_VALUE_STRING); ro_etag = dpl_sbuf_get_str(var->val->string); start_etag = strchr(ro_etag, '"'); if (start_etag == NULL) { start_etag = ro_etag; end_etag = start_etag + strlen(start_etag); } else { start_etag += 1; // go after the " char end_etag = strchr(start_etag, '"'); } *etagp = strndup(start_etag, end_etag - start_etag); if (*etagp == NULL) { ret = DPL_ENOMEM; goto end; } } ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); return ret; }
dpl_status_t dpl_s3_put(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, const dpl_option_t *option, dpl_ftype_t object_type, const dpl_condition_t *condition, const dpl_range_t *range, const dpl_dict_t *metadata, const dpl_sysmd_t *sysmd, const char *data_buf, unsigned int data_len, const dpl_dict_t *query_params, dpl_sysmd_t *returned_sysmdp, char **locationp) { int ret, ret2; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_s3_req_mask_t req_mask = 0u; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_PUT); if (NULL == bucket) { ret = DPL_EINVAL; goto end; } ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } dpl_req_set_data(req, data_buf, data_len); dpl_req_add_behavior(req, DPL_BEHAVIOR_MD5); if (sysmd) { if (sysmd->mask & DPL_SYSMD_MASK_CANNED_ACL) dpl_req_set_canned_acl(req, sysmd->canned_acl); if (sysmd->mask & DPL_SYSMD_MASK_STORAGE_CLASS) dpl_req_set_storage_class(req, sysmd->storage_class); } if (NULL != metadata) { ret2 = dpl_req_add_metadata(req, metadata); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } ret2 = dpl_s3_req_build(req, req_mask, &headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_s3_add_authorization_to_headers(req, headers_request, NULL, NULL); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; //buffer iov[n_iov].iov_base = (void *)data_buf; iov[n_iov].iov_len = data_len; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; ret = ret2; goto end; } ret2 = dpl_read_http_reply(conn, 1, NULL, NULL, &headers_reply, &connection_close); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
dpl_status_t dpl_s3_list_bucket(dpl_ctx_t *ctx, const char *bucket, const char *prefix, const char *delimiter, const int max_keys, dpl_vec_t **objectsp, dpl_vec_t **common_prefixesp, char **locationp) { int ret, ret2; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; char *data_buf = NULL; u_int data_len; dpl_vec_t *objects = NULL; dpl_vec_t *common_prefixes = NULL; dpl_dict_t *query_params = NULL; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_s3_req_mask_t req_mask = 0u; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_GET); if (NULL == bucket) { ret = DPL_EINVAL; goto end; } ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_set_resource(req, "/"); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } query_params = dpl_dict_new(13); if (NULL == query_params) { ret = DPL_ENOMEM; goto end; } if (NULL != prefix) { ret2 = dpl_dict_add(query_params, "prefix", prefix, 0); if (DPL_SUCCESS != ret2) { ret = DPL_ENOMEM; goto end; } } if (NULL != delimiter) { ret2 = dpl_dict_add(query_params, "delimiter", delimiter, 0); if (DPL_SUCCESS != ret2) { ret = DPL_ENOMEM; goto end; } } if (-1 != max_keys) { char tmp[32] = ""; snprintf(tmp, sizeof tmp, "%d", max_keys); ret2 = dpl_dict_add(query_params, "max-keys", tmp, 0); if (DPL_SUCCESS != ret2) { ret = DPL_ENOMEM; goto end; } } ret2 = dpl_s3_req_build(req, req_mask, &headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, query_params, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; ret = ret2; goto end; } ret2 = dpl_read_http_reply(conn, 1, &data_buf, &data_len, &headers_reply, &connection_close); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } objects = dpl_vec_new(2, 2); if (NULL == objects) { ret = DPL_ENOMEM; goto end; } common_prefixes = dpl_vec_new(2, 2); if (NULL == common_prefixes) { ret = DPL_ENOMEM; goto end; } ret = dpl_s3_parse_list_bucket(ctx, data_buf, data_len, objects, common_prefixes); if (DPL_SUCCESS != ret) { ret = ret2; goto end; } if (NULL != objectsp) { *objectsp = objects; objects = NULL; //consume it } if (NULL != common_prefixesp) { *common_prefixesp = common_prefixes; common_prefixes = NULL; //consume it } ret = DPL_SUCCESS; end: if (NULL != objects) dpl_vec_objects_free(objects); if (NULL != common_prefixes) dpl_vec_common_prefixes_free(common_prefixes); if (NULL != data_buf) free(data_buf); if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != query_params) dpl_dict_free(query_params); if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
/** * make a bucket * * @param ctx * @param bucket * @param location_constraint * @param sysmd * * @return */ dpl_status_t dpl_s3_make_bucket(dpl_ctx_t *ctx, const char *bucket, const dpl_sysmd_t *sysmd, char **locationp) { int ret, ret2; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; char *location_constraint_str; char data_str[1024]; u_int data_len; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_s3_req_mask_t req_mask = 0u; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_PUT); if (NULL == bucket) { ret = DPL_EINVAL; goto end; } ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_set_resource(req, "/"); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (sysmd) { if (sysmd->mask & DPL_SYSMD_MASK_LOCATION_CONSTRAINT) { if (DPL_LOCATION_CONSTRAINT_US_STANDARD == sysmd->location_constraint) { data_str[0] = 0; data_len = 0; } else { location_constraint_str = dpl_location_constraint_str(sysmd->location_constraint); if (NULL == location_constraint_str) { ret = DPL_ENOMEM; goto end; } snprintf(data_str, sizeof (data_str), "<CreateBucketConfiguration xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">\n" "<LocationConstraint>%s</LocationConstraint>\n" "</CreateBucketConfiguration>\n", location_constraint_str); data_len = strlen(data_str); } } else { data_str[0] = 0; data_len = 0; } } else { data_str[0] = 0; data_len = 0; } dpl_req_set_data(req, data_str, data_len); if (sysmd) { if (sysmd->mask & DPL_SYSMD_MASK_CANNED_ACL) dpl_req_set_canned_acl(req, sysmd->canned_acl); if (sysmd->mask & DPL_SYSMD_MASK_STORAGE_CLASS) dpl_req_set_storage_class(req, sysmd->storage_class); } //build request ret2 = dpl_s3_req_build(req, req_mask, &headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; //buffer iov[n_iov].iov_base = data_str; iov[n_iov].iov_len = data_len; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; ret = ret2; goto end; } ret2 = dpl_read_http_reply(conn, 1, NULL, NULL, &headers_reply, &connection_close); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
dpl_status_t dpl_s3_genurl(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, const dpl_option_t *option, time_t expires, char *buf, unsigned int len, unsigned int *lenp, char **locationp) { int ret, ret2; dpl_dict_t *headers_request = NULL; dpl_req_t *req = NULL; dpl_s3_req_mask_t req_mask = 0u; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_GET); dpl_req_add_behavior(req, DPL_BEHAVIOR_QUERY_STRING); if (NULL == bucket) { ret = DPL_EINVAL; goto end; } ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } dpl_req_set_expires(req, expires); //build request ret2 = dpl_s3_req_build(req, req_mask, &headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_s3_req_gen_url(req, headers_request, buf, len, lenp); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret = DPL_SUCCESS; end: if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
dpl_status_t dpl_s3_copy(dpl_ctx_t *ctx, const char *src_bucket, const char *src_resource, const char *src_subresource, const char *dst_bucket, const char *dst_resource, const char *dst_subresource, const dpl_option_t *option, dpl_ftype_t object_type, dpl_copy_directive_t copy_directive, const dpl_dict_t *metadata, const dpl_sysmd_t *sysmd, const dpl_condition_t *condition, char **locationp) { int ret, ret2; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_s3_req_mask_t req_mask = 0u; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_PUT); req_mask |= DPL_S3_REQ_COPY; if (NULL != condition) dpl_req_set_copy_source_condition(req, condition); if (NULL == src_bucket || NULL == dst_bucket) { ret = DPL_EINVAL; goto end; } ret2 = dpl_req_set_bucket(req, dst_bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_set_resource(req, dst_resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != dst_subresource) { ret2 = dpl_req_set_subresource(req, dst_subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } ret2 = dpl_req_set_src_bucket(req, src_bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_set_src_resource(req, src_resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != src_subresource) { ret2 = dpl_req_set_src_subresource(req, src_subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } dpl_req_set_copy_directive(req, copy_directive); if (NULL != metadata) { ret2 = dpl_req_add_metadata(req, metadata); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (sysmd) { if (sysmd->mask & DPL_SYSMD_MASK_CANNED_ACL) dpl_req_set_canned_acl(req, sysmd->canned_acl); } //build request ret2 = dpl_s3_req_build(req, req_mask, &headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; ret = DPL_FAILURE; goto end; } ret2 = dpl_read_http_reply(conn, 1, NULL, NULL, &headers_reply, &connection_close); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
dpl_status_t dpl_s3_list_all_my_buckets(dpl_ctx_t *ctx, dpl_vec_t **vecp, char **locationp) { int ret, ret2; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; char *data_buf = NULL; u_int data_len; dpl_vec_t *vec = NULL; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_s3_req_mask_t req_mask = 0u; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_GET); ret2 = dpl_req_set_resource(req, "/"); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } //build request ret2 = dpl_s3_req_build(req, req_mask, &headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); ret2 = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; ret = ret2; goto end; } ret2 = dpl_read_http_reply(conn, 1, &data_buf, &data_len, &headers_reply, &connection_close); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } vec = dpl_vec_new(2, 2); if (NULL == vec) { ret = DPL_ENOMEM; goto end; } ret2 = dpl_s3_parse_list_all_my_buckets(ctx, data_buf, data_len, vec); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != vecp) { *vecp = vec; vec = NULL; //consume vec } ret = DPL_SUCCESS; end: if (NULL != vec) dpl_vec_buckets_free(vec); if (NULL != data_buf) free(data_buf); if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
dpl_status_t dpl_s3_get_buffered(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, const dpl_option_t *option, dpl_ftype_t object_type, const dpl_condition_t *condition, const dpl_range_t *range, dpl_metadatum_func_t metadatum_func, dpl_dict_t **metadatap, dpl_sysmd_t *sysmdp, dpl_buffer_func_t buffer_func, void *cb_arg, char **locationp) { int ret, ret2; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; dpl_dict_t *headers_request = NULL; dpl_req_t *req = NULL; struct get_conven gc; int http_status; dpl_s3_req_mask_t req_mask = 0u; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); memset(&gc, 0, sizeof (gc)); gc.metadata = dpl_dict_new(13); if (NULL == gc.metadata) { ret = DPL_ENOMEM; goto end; } gc.sysmdp = sysmdp; gc.metadatum_func = metadatum_func; gc.buffer_func = buffer_func; gc.cb_arg = cb_arg; req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_GET); if (NULL == bucket) { ret = DPL_EINVAL; goto end; } ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (NULL != condition) { dpl_req_set_condition(req, condition); } //build request ret2 = dpl_s3_req_build(req, req_mask, &headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); gc.connection_close = 1; ret = ret2; goto end; } ret2 = dpl_read_http_reply_buffered(conn, 1, &http_status, cb_get_header, cb_get_buffer, &gc); if (DPL_SUCCESS != ret2) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "read http answer failed"); gc.connection_close = 1; ret = ret2; goto end; } if (!conn->ctx->keep_alive) gc.connection_close = 1; if (NULL != metadatap) { *metadatap = gc.metadata; gc.metadata = NULL; } //map http_status to relevant value ret = dpl_map_http_status(http_status); //caller is responsible for logging the event end: if (NULL != conn) { if (1 == gc.connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != gc.metadata) dpl_dict_free(gc.metadata); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
dpl_status_t dpl_s3_get(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, const dpl_option_t *option, dpl_ftype_t object_type, const dpl_condition_t *condition, const dpl_range_t *range, char **data_bufp, unsigned int *data_lenp, dpl_dict_t **metadatap, dpl_sysmd_t *sysmdp, char **locationp) { int ret, ret2; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; char *data_buf = NULL; u_int data_len; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_s3_req_mask_t req_mask = 0u; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_GET); if (NULL == bucket) { ret = DPL_EINVAL; goto end; } ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (NULL != condition) { dpl_req_set_condition(req, condition); } if (range) { ret2 = dpl_req_add_range(req, range->start, range->end); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } //build request ret2 = dpl_s3_req_build(req, req_mask, &headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; ret = ret2; goto end; } ret2 = dpl_read_http_reply(conn, 1, &data_buf, &data_len, &headers_reply, &connection_close); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_s3_get_metadata_from_headers(headers_reply, metadatap, sysmdp); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != data_bufp) { *data_bufp = data_buf; data_buf = NULL; //consume it } if (NULL != data_lenp) *data_lenp = data_len; //dpl_dict_print(headers_reply); ret = DPL_SUCCESS; end: if (NULL != data_buf) free(data_buf); if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
dpl_status_t dpl_s3_stream_multipart_init(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char **uploadidp) { dpl_status_t ret; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; char *replybuf = NULL; unsigned int replybuflen = 0; req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_POST); if (NULL == bucket) { ret = DPL_EINVAL; goto end; } ret = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret) goto end; ret = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret) goto end; ret = dpl_req_set_subresource(req, "uploads"); if (DPL_SUCCESS != ret) goto end; ret = dpl_s3_req_build(req, 0u, &headers_request); if (DPL_SUCCESS != ret) goto end; ret = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret) goto end; ret = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret) goto end; ret = dpl_s3_add_authorization_to_headers(req, headers_request, NULL, NULL); if (DPL_SUCCESS != ret) goto end; ret = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret) goto end; iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; goto end; } ret = dpl_read_http_reply_ext(conn, 1, 0, &replybuf, &replybuflen, &headers_reply, &connection_close); if (DPL_SUCCESS != ret) goto end; ret = _multipart_parse_init(ctx, replybuf, replybuflen, uploadidp); if (DPL_SUCCESS != ret) goto end; ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); return ret; }
dpl_status_t dpl_s3_delete_bucket(dpl_ctx_t *ctx, const char *bucket, char **locationp) { int ret, ret2; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_s3_req_mask_t req_mask = 0u; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_DELETE); if (NULL == bucket) { ret = DPL_EINVAL; goto end; } ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_set_resource(req, "/"); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_s3_req_build(req, req_mask, &headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; ret = ret2; goto end; } ret2 = dpl_read_http_reply(conn, 1, NULL, NULL, &headers_reply, &connection_close); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
dpl_status_t dpl_s3_stream_multipart_complete(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *uploadid, struct json_object *parts, unsigned int n_parts, const dpl_dict_t *metadata, const dpl_sysmd_t *sysmd) { dpl_status_t ret; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; char subresource[strlen(uploadid) + 10 /* for 'uploadId=' */]; char *databuf = NULL; unsigned int databuflen = 0; char *replybuf = NULL; unsigned int replybuflen = 0; snprintf(subresource, sizeof(subresource), "uploadId=%s", uploadid); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_POST); if (NULL == bucket) { ret = DPL_EINVAL; goto end; } ret = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret) goto end; ret = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret) goto end; ret = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret) goto end; ret = multipart_complete_gen_body(ctx, parts, n_parts, &databuf, &databuflen); if (DPL_SUCCESS != ret) goto end; dpl_req_set_data(req, databuf, databuflen); dpl_req_add_behavior(req, DPL_BEHAVIOR_MD5); if (sysmd) { if (sysmd->mask & DPL_SYSMD_MASK_CANNED_ACL) dpl_req_set_canned_acl(req, sysmd->canned_acl); if (sysmd->mask & DPL_SYSMD_MASK_STORAGE_CLASS) dpl_req_set_storage_class(req, sysmd->storage_class); } if (NULL != metadata) { ret = dpl_req_add_metadata(req, metadata); if (DPL_SUCCESS != ret) goto end; } ret = dpl_s3_req_build(req, 0u, &headers_request); if (DPL_SUCCESS != ret) goto end; ret = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret) goto end; ret = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret) goto end; ret = dpl_s3_add_authorization_to_headers(req, headers_request, NULL, NULL); if (DPL_SUCCESS != ret) goto end; ret = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret) goto end; iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; //buffer iov[n_iov].iov_base = (void *)databuf; iov[n_iov].iov_len = databuflen; n_iov++; ret = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; goto end; } ret = dpl_read_http_reply_ext(conn, 1, 0, &replybuf, &replybuflen, &headers_reply, &connection_close); if (DPL_SUCCESS != ret) goto end; ret = _multipart_parse_complete(ctx, replybuf, replybuflen); if (DPL_SUCCESS != ret) goto end; ret = DPL_SUCCESS; end: free(databuf); if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); return ret; }
dpl_status_t dpl_srws_delete(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, const dpl_option_t *option, dpl_ftype_t object_type, const dpl_condition_t *condition, char **locationp) { int ret, ret2; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_srws_req_mask_t req_mask = 0u; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_DELETE); ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (option) { if (option->mask & DPL_OPTION_LAZY) req_mask |= DPL_SRWS_REQ_LAZY; } //build request ret2 = dpl_srws_req_build(req, req_mask, &headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); ret2 = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; ret = ret2; goto end; } ret2 = dpl_read_http_reply(conn, 1, NULL, NULL, &headers_reply, &connection_close); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
dpl_status_t dpl_sproxyd_get_id(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, const dpl_option_t *option, dpl_ftype_t object_type, const dpl_condition_t *condition, const dpl_range_t *range, char **data_bufp, unsigned int *data_lenp, dpl_dict_t **metadatap, dpl_sysmd_t *sysmdp, char **locationp) { int ret, ret2; dpl_conn_t *conn = NULL; char header[dpl_header_size]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; char *data_buf = NULL; u_int data_len; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_sproxyd_req_mask_t req_mask = 0u; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_GET); ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (NULL != condition) { dpl_req_set_condition(req, condition); } if (range) { ret2 = dpl_req_add_range(req, range->start, range->end); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (option) { if (option->mask & DPL_OPTION_CONSISTENT) req_mask |= DPL_SPROXYD_REQ_CONSISTENT; } dpl_req_set_object_type(req, object_type); //build request ret2 = dpl_sproxyd_req_build(req, req_mask, -1, &headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); ret2 = dpl_try_connect(ctx, req, &conn); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_add_host_to_headers(req, headers_request); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed"); connection_close = 1; ret = ret2; goto end; } if (option && option->mask & DPL_OPTION_NOALLOC) { data_buf = *data_bufp; data_len = *data_lenp; } ret2 = dpl_read_http_reply_ext(conn, 1, (option && option->mask & DPL_OPTION_NOALLOC) ? 1 : 0, &data_buf, &data_len, &headers_reply, &connection_close); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_sproxyd_get_metadata_from_headers(headers_reply, metadatap, sysmdp); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != data_bufp) { *data_bufp = data_buf; data_buf = NULL; //consume it } if (NULL != data_lenp) *data_lenp = data_len; ret = DPL_SUCCESS; end: if ((option && !(option->mask & DPL_OPTION_NOALLOC)) && NULL != data_buf) free(data_buf); if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
dpl_status_t dpl_cdmi_get(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, dpl_ftype_t object_type, const dpl_condition_t *condition, char **data_bufp, unsigned int *data_lenp, dpl_dict_t **metadatap) { char *host; int ret, ret2; dpl_conn_t *conn = NULL; char header[1024]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; char *data_buf = NULL; u_int data_len; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_dict_t *metadata = NULL; dpl_req_t *req = NULL; req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_GET); if (NULL != bucket) { ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (NULL != condition) { dpl_req_set_condition(req, condition); } //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); dpl_req_set_object_type(req, object_type); //build request ret2 = dpl_cdmi_req_build(req, &headers_request, NULL, NULL); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } host = dpl_dict_get_value(headers_request, "Host"); if (NULL == host) { ret = DPL_FAILURE; goto end; } conn = dpl_conn_open_host(ctx, host, ctx->port); if (NULL == conn) { ret = DPL_FAILURE; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPLERR(1, "writev failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } ret2 = dpl_read_http_reply(conn, 1, &data_buf, &data_len, &headers_reply); if (DPL_SUCCESS != ret2) { if (DPL_ENOENT == ret2) { ret = DPL_ENOENT; goto end; } else { DPLERR(0, "read http answer failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } } else { connection_close = dpl_connection_close(ctx, headers_reply); } (void) dpl_log_event(ctx, "DATA", "OUT", data_len); if (NULL != data_bufp) { *data_bufp = data_buf; data_buf = NULL; //consume it } if (NULL != data_lenp) *data_lenp = data_len; if (NULL != metadatap) { *metadatap = metadata; metadata = NULL; //consume it } ret = DPL_SUCCESS; end: if (NULL != data_buf) free(data_buf); if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != metadata) dpl_dict_free(metadata); if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPRINTF("ret=%d\n", ret); return ret; }
int main(int argc, char **argv) { int ret; char opt; dpl_req_t *req = NULL; dpl_dict_t *headers_request = NULL; dpl_dict_t *query_params = NULL; char header[8192]; u_int header_len; optind = 0; ret = dpl_init(); if (DPL_SUCCESS != ret) { fprintf(stderr, "error initing droplet\n"); exit(1); } ctx = dpl_ctx_new(NULL, NULL); if (NULL == ctx) { fprintf(stderr, "error creating droplet ctx\n"); exit(1); } req = dpl_req_new(ctx); if (NULL == req) { fprintf(stderr, "error creating req\n"); exit(1); } while ((opt = getopt(argc, argv, "m:b:r:s:Mc:C:et:q:")) != -1) switch (opt) { case 'm': { dpl_method_t method; method = dpl_method(optarg); if (-1 == method) { fprintf(stderr, "unknown method %s\n", optarg); break ; } dpl_req_set_method(req, method); break ; } case 'b': { ret = dpl_req_set_bucket(req, optarg); if (DPL_SUCCESS != ret) { fprintf(stderr, "error setting bucket %s\n", optarg); exit(1); } break ; } case 'r': { ret = dpl_req_set_resource(req, optarg); if (DPL_SUCCESS != ret) { fprintf(stderr, "error setting resource %s: %s (%d)\n", optarg, dpl_status_str(ret), ret); exit(1); } break ; } case 's': { ret = dpl_req_set_subresource(req, optarg); if (DPL_SUCCESS != ret) { fprintf(stderr, "error setting subresource %s: %s (%d)\n", optarg, dpl_status_str(ret), ret); exit(1); } break ; } case 'M': { dpl_req_add_behavior(req, DPL_BEHAVIOR_MD5); break ; } case 'c': { int fd; struct stat st; dpl_chunk_t *chunk; ssize_t cc; fd = open(optarg, O_RDONLY); if (-1 == fd) xperror("open"); ret = fstat(fd, &st); if (-1 == ret) xperror("stat"); chunk = xmalloc(sizeof (*chunk)); chunk->buf = xmalloc(st.st_size); cc = read(fd, chunk->buf, st.st_size); if (cc != st.st_size) { fprintf(stderr, "short read\n"); exit(1); } chunk->len = st.st_size; dpl_req_set_chunk(req, chunk); close(fd); break ; } case 'C': { ret = dpl_req_set_content_type(req, optarg); if (DPL_SUCCESS != ret) { fprintf(stderr, "error setting content_type %s: %s (%d)\n", optarg, dpl_status_str(ret), ret); exit(1); } break ; } case 'e': { dpl_req_add_behavior(req, DPL_BEHAVIOR_EXPECT); break ; } case 't': { ctx->trace_level = strtoul(optarg, NULL, 0); break ; } case 'q': { query_params = dpl_parse_query_params(optarg); if (NULL == query_params) { fprintf(stderr, "error parsing query_params\n"); exit(1); } break ; } case '?': default: usage(); } argc -= optind; argv += optind; #if 0 { extern void test_strrstr(); test_strrstr(); exit(0); } #endif if (0 != argc) { usage(); } ret = dpl_req_build(req, &headers_request); if (DPL_SUCCESS != ret) { fprintf(stderr, "error in request: %s (%d)\n", dpl_status_str(ret), ret); exit(1); } ret = dpl_req_gen_http_request(req, headers_request, query_params, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret) { fprintf(stderr, "error in request: %s (%d)\n", dpl_status_str(ret), ret); exit(1); } ret = fwrite(header, header_len, 1, stdout); if (1 != ret) { fprintf(stderr, "short write\n"); exit(1); } dpl_dict_free(headers_request); if (NULL != query_params) dpl_dict_free(query_params); if (NULL != req->chunk) { free(req->chunk->buf); free(req->chunk); } dpl_req_free(req); dpl_ctx_free(ctx); dpl_free(); return 0; }
static dpl_status_t delete_all(dpl_ctx_t *ctx, const char *bucket, dpl_locators_t *locators, struct dall_req *dctx, dpl_vec_t **objectsp) { dpl_status_t ret; struct iovec iov[10]; int n_iov = 0; char header[dpl_header_size]; u_int header_len; dctx->req = dpl_req_new(ctx); if (dctx->req == NULL) return DPL_ENOMEM; dpl_req_set_method(dctx->req, DPL_METHOD_POST); if (bucket == NULL) return DPL_EINVAL; ret = dpl_req_set_bucket(dctx->req, bucket); if (ret != DPL_SUCCESS) return ret; ret = dpl_req_set_resource(dctx->req, "/"); if (ret != DPL_SUCCESS) return ret; ret = dpl_req_set_subresource(dctx->req, "delete"); if (ret != DPL_SUCCESS) return ret; dctx->query_params = dpl_dict_new(1); if (dctx->query_params == NULL) return ENOMEM; /* Note: Juste for authentification signature calcul */ ret = dpl_dict_add(dctx->query_params, "delete", "", 0); if (DPL_SUCCESS != ret) return ret; dctx->data = dpl_sbuf_new(4096); if (dctx->data == NULL) return DPL_ENOMEM; ret = get_delete_data_content(ctx, locators, dctx->data); if (ret != DPL_SUCCESS) return ret; dpl_req_set_data(dctx->req, dctx->data->buf, dctx->data->len); dpl_req_add_behavior(dctx->req, DPL_BEHAVIOR_MD5); ret = dpl_s3_req_build(dctx->req, 0, &dctx->headers); if (ret != DPL_SUCCESS) return ret; ret = dpl_try_connect(ctx, dctx->req, &dctx->conn); if (ret != DPL_SUCCESS) return ret; ret = dpl_add_host_to_headers(dctx->req, dctx->headers); if (ret != DPL_SUCCESS) return ret; ret = dpl_s3_add_authorization_to_headers(dctx->req, dctx->headers, dctx->query_params, NULL); if (ret != DPL_SUCCESS) return ret; ret = dpl_req_gen_http_request(ctx, dctx->req, dctx->headers, NULL, header, sizeof(header), &header_len); if (ret != DPL_SUCCESS) return ret; // Headers iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; // Final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; // Data iov[n_iov].iov_base = (void *) dctx->data->buf; iov[n_iov].iov_len = dctx->data->len; n_iov++; ret = dpl_conn_writev_all(dctx->conn, iov, n_iov, ctx->write_timeout); if (ret != DPL_SUCCESS) { dctx->connection_close = 1; return ret; } ret = dpl_read_http_reply(dctx->conn, 1, &dctx->answer_data, &dctx->answer_len, NULL, &dctx->connection_close); if (dctx->answer_len > 0) { dpl_status_t parse_ret; dctx->objects = dpl_vec_new(2, 2); if (dctx->objects == NULL) return DPL_ENOMEM; parse_ret = dpl_s3_parse_delete_all(ctx, dctx->answer_data, dctx->answer_len, dctx->objects); if (parse_ret == DPL_SUCCESS && objectsp != NULL) { *objectsp = dctx->objects; dctx->objects = NULL; } if (ret == DPL_SUCCESS) ret = parse_ret; } return ret; }