From efaacda5e417d9cd5f14c09e4a195a09c814e451 Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Tue, 16 Jan 2024 12:29:57 -0600 Subject: [PATCH] Make server connection info file-local (#86) --- src/rest_vol.c | 193 ++++++++++++++++++--------------------- src/rest_vol.h | 30 +++--- src/rest_vol_attr.c | 142 +++++++++++++++++++++++++--- src/rest_vol_config.h.in | 12 +-- src/rest_vol_dataset.c | 39 ++++++-- src/rest_vol_datatype.c | 14 ++- src/rest_vol_file.c | 93 +++++++++++++------ src/rest_vol_group.c | 29 ++++-- src/rest_vol_link.c | 80 ++++++++++++++-- src/rest_vol_object.c | 106 +++++++++++++++++---- 10 files changed, 533 insertions(+), 205 deletions(-) diff --git a/src/rest_vol.c b/src/rest_vol.c index 630c3a95..84dfa66d 100644 --- a/src/rest_vol.c +++ b/src/rest_vol.c @@ -68,11 +68,6 @@ char curl_err_buf[CURL_ERROR_SIZE]; */ struct curl_slist *curl_headers = NULL; -/* - * Saved copy of the base URL for operating on - */ -char *base_URL = NULL; - #ifdef RV_TRACK_MEM_USAGE /* * Counter to keep track of the currently allocated amount of bytes @@ -151,12 +146,15 @@ const char *allocated_size_keys[] = {"allocated_size", (const char *)0}; /* JSON key to retrieve the version of server from a request to a file. */ const char *server_version_keys[] = {"version", (const char *)0}; +/* Used for cURL's base URL if the connection is through a local socket */ +const char *socket_base_url = "0"; + /* Internal initialization/termination functions which are called by * the public functions H5rest_init() and H5rest_term() */ static herr_t H5_rest_init(hid_t vipl_id); static herr_t H5_rest_term(void); -static herr_t H5_rest_authenticate_with_AD(H5_rest_ad_info_t *ad_info); +static herr_t H5_rest_authenticate_with_AD(H5_rest_ad_info_t *ad_info, const char *base_URL); /* Introspection callbacks */ static herr_t H5_rest_get_conn_cls(void *obj, H5VL_get_conn_lvl_t lvl, const struct H5VL_class_t **conn_cls); @@ -609,12 +607,6 @@ H5_rest_term(void) if (!H5_rest_initialized_g) FUNC_GOTO_DONE(SUCCEED); - /* Free base URL */ - if (base_URL) { - RV_free(base_URL); - base_URL = NULL; - } - /* Free memory for cURL response buffer */ if (response_buffer.buffer) { RV_free(response_buffer.buffer); @@ -684,9 +676,6 @@ H5Pset_fapl_rest_vol(hid_t fapl_id) if ((ret_value = H5Pset_vol(fapl_id, H5_rest_id_g, NULL)) < 0) FUNC_GOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't set REST VOL connector in FAPL"); - if (H5_rest_set_connection_information() < 0) - FUNC_GOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't set REST VOL connector connection information"); - done: PRINT_ERROR_STACK; @@ -725,16 +714,15 @@ H5rest_get_object_uri(hid_t obj_id) * June, 2018 */ herr_t -H5_rest_set_connection_information(void) +H5_rest_set_connection_information(server_info_t *server_info) { H5_rest_ad_info_t ad_info; - const char *URL; - size_t URL_len = 0; FILE *config_file = NULL; herr_t ret_value = SUCCEED; - if (base_URL) - FUNC_GOTO_DONE(SUCCEED); + const char *username = NULL; + const char *password = NULL; + const char *base_URL = NULL; memset(&ad_info, 0, sizeof(ad_info)); @@ -743,50 +731,16 @@ H5_rest_set_connection_information(void) * the environment. */ - if ((URL = getenv("HSDS_ENDPOINT"))) { - - if (!strncmp(URL, UNIX_SOCKET_PREFIX, strlen(UNIX_SOCKET_PREFIX))) { - /* This is just a placeholder URL for curl's syntax, its specific value is unimportant */ - URL = "0"; - URL_len = 1; - - if (NULL == (base_URL = (char *)RV_malloc(URL_len + 1))) - FUNC_GOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, - "can't allocate space necessary for placeholder base URL"); - - strcpy(base_URL, URL); - } - else { - /* - * Save a copy of the base URL being worked on so that operations like - * creating a Group can be redirected to "base URL"/groups by building - * off of the base URL supplied. - */ - URL_len = strlen(URL); + if (base_URL = getenv("HSDS_ENDPOINT")) { - if (NULL == (base_URL = (char *)RV_malloc(URL_len + 1))) - FUNC_GOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, - "can't allocate space necessary for placeholder base URL"); + username = getenv("HSDS_USERNAME"); + password = getenv("HSDS_PASSWORD"); - strcpy(base_URL, URL); + if (!strncmp(base_URL, UNIX_SOCKET_PREFIX, strlen(UNIX_SOCKET_PREFIX))) { + base_URL = socket_base_url; } - const char *username = getenv("HSDS_USERNAME"); - const char *password = getenv("HSDS_PASSWORD"); - - if (username || password) { - /* Attempt to set authentication information */ - if (username && strlen(username)) { - if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, username)) - FUNC_GOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "can't set username: %s", curl_err_buf); - } /* end if */ - - if (password && strlen(password)) { - if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, password)) - FUNC_GOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "can't set password: %s", curl_err_buf); - } /* end if */ - } /* end if */ - else { + if (!username && !password) { const char *clientID = getenv("HSDS_AD_CLIENT_ID"); const char *tenantID = getenv("HSDS_AD_TENANT_ID"); const char *resourceID = getenv("HSDS_AD_RESOURCE_ID"); @@ -804,7 +758,7 @@ H5_rest_set_connection_information(void) } /* end if */ /* Attempt authentication with Active Directory */ - if (H5_rest_authenticate_with_AD(&ad_info) < 0) + if (H5_rest_authenticate_with_AD(&ad_info, base_URL) < 0) FUNC_GOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't authenticate with Active Directory"); } /* end else */ } /* end if */ @@ -880,33 +834,14 @@ H5_rest_set_connection_information(void) if (!strcmp(key, "hs_endpoint")) { if (val) { - /* - * Save a copy of the base URL being worked on so that operations like - * creating a Group can be redirected to "base URL"/groups by building - * off of the base URL supplied. - */ - URL_len = strlen(val); - - if (NULL == (base_URL = (char *)RV_malloc(URL_len + 1))) - FUNC_GOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, - "can't allocate space necessary for placeholder base URL"); - - strcpy(base_URL, val); - + if (!strncmp(base_URL, UNIX_SOCKET_PREFIX, strlen(UNIX_SOCKET_PREFIX))) { + base_URL = socket_base_url; + } + else { + base_URL = val; + } } /* end if */ } /* end if */ - else if (!strcmp(key, "hs_username")) { - if (val && strlen(val)) { - if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, val)) - FUNC_GOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "can't set username: %s", curl_err_buf); - } /* end if */ - } /* end else if */ - else if (!strcmp(key, "hs_password")) { - if (val && strlen(val)) { - if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, val)) - FUNC_GOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "can't set password: %s", curl_err_buf); - } /* end if */ - } /* end else if */ else if (!strcmp(key, "hs_ad_app_id")) { if (val && strlen(val)) strncpy(ad_info.clientID, val, sizeof(ad_info.clientID) - 1); @@ -929,7 +864,7 @@ H5_rest_set_connection_information(void) /* Attempt authentication with Active Directory if ID values are present */ if (ad_info.clientID[0] != '\0' && ad_info.tenantID[0] != '\0' && ad_info.resourceID[0] != '\0') - if (H5_rest_authenticate_with_AD(&ad_info) < 0) + if (!base_URL || (H5_rest_authenticate_with_AD(&ad_info, base_URL) < 0)) FUNC_GOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't authenticate with Active Directory"); } /* end else */ @@ -938,10 +873,45 @@ H5_rest_set_connection_information(void) "must specify a base URL - please set HSDS_ENDPOINT environment variable or create a " "config file"); + /* Copy server information */ + if (server_info) { + if (username) { + if ((server_info->username = RV_calloc(strlen(username) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't allocate space for username"); + + strcpy(server_info->username, username); + } + + if (password) { + if ((server_info->password = RV_calloc(strlen(password) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't allocate space for password"); + + strcpy(server_info->password, password); + } + + if (base_URL) { + if ((server_info->base_URL = RV_calloc(strlen(base_URL) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't allocate space for URL"); + + strcpy(server_info->base_URL, base_URL); + } + } + done: if (config_file) fclose(config_file); + if (ret_value < 0 && server_info) { + RV_free(server_info->username); + server_info->username = NULL; + + RV_free(server_info->password); + server_info->password = NULL; + + RV_free(server_info->base_URL); + server_info->base_URL = NULL; + } + PRINT_ERROR_STACK; return ret_value; @@ -965,7 +935,7 @@ H5_rest_set_connection_information(void) *------------------------------------------------------------------------- */ static herr_t -H5_rest_authenticate_with_AD(H5_rest_ad_info_t *ad_info) +H5_rest_authenticate_with_AD(H5_rest_ad_info_t *ad_info, const char *base_URL) { const char *access_token_key[] = {"access_token", (const char *)0}; const char *refresh_token_key[] = {"refresh_token", (const char *)0}; @@ -2031,6 +2001,7 @@ RV_find_object_by_path(RV_object_t *parent_obj, const char *obj_path, H5I_type_t char *url_encoded_path_name = NULL; const char *ext_filename = NULL; const char *ext_obj_path = NULL; + const char *base_URL; char request_url[URL_MAX_LENGTH]; long http_response; int url_len = 0; @@ -2047,13 +2018,14 @@ RV_find_object_by_path(RV_object_t *parent_obj, const char *obj_path, H5I_type_t if (H5I_FILE != parent_obj->obj_type && H5I_GROUP != parent_obj->obj_type && H5I_DATATYPE != parent_obj->obj_type && H5I_DATASET != parent_obj->obj_type) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent object not a file, group, datatype or dataset"); - + if ((base_URL = parent_obj->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent object does not have valid server URL"); #ifdef RV_CONNECTOR_DEBUG printf("-> Finding object by path '%s' from parent object of type %s with URI %s\n\n", obj_path, object_type_to_string(parent_obj->obj_type), parent_obj->URI); #endif - version = parent_obj->domain->u.file.server_version; + version = parent_obj->domain->u.file.server_info.version; /* In order to not confuse the server, make sure the path has no leading spaces */ while (*obj_path == ' ') @@ -2438,10 +2410,11 @@ RV_parse_creation_properties_callback(yajl_val parse_tree, char **GCPL_buf_out) herr_t RV_copy_object_loc_info_callback(char *HTTP_response, void *callback_data_in, void *callback_data_out) { - yajl_val parse_tree = NULL, key_obj; - char *parsed_string; - loc_info *loc_info_out = (loc_info *)callback_data_out; - herr_t ret_value = SUCCEED; + yajl_val parse_tree = NULL, key_obj; + char *parsed_string; + loc_info *loc_info_out = (loc_info *)callback_data_out; + server_info_t *server_info = (server_info_t *)callback_data_in; + herr_t ret_value = SUCCEED; char *GCPL_buf = NULL; @@ -2458,6 +2431,8 @@ RV_copy_object_loc_info_callback(char *HTTP_response, void *callback_data_in, vo FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "HTTP response buffer was NULL"); if (!loc_info_out) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "output buffer was NULL"); + if (!server_info) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "server info was NULL"); if (NULL == (parse_tree = yajl_tree_parse(HTTP_response, NULL, 0))) FUNC_GOTO_ERROR(H5E_OBJECT, H5E_PARSEERROR, FAIL, "parsing JSON failed"); @@ -2519,14 +2494,28 @@ RV_copy_object_loc_info_callback(char *HTTP_response, void *callback_data_in, vo FUNC_GOTO_ERROR(H5E_CALLBACK, H5E_CANTALLOC, FAIL, "failed to allocate memory for new domain path"); - strncpy(new_domain->u.file.filepath_name, found_domain.u.file.filepath_name, - strlen(found_domain.u.file.filepath_name) + 1); + strcpy(new_domain->u.file.filepath_name, found_domain.u.file.filepath_name); + + if ((new_domain->u.file.server_info.username = RV_malloc(strlen(server_info->username) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't allocate space for copied username"); + + strcpy(new_domain->u.file.server_info.username, server_info->username); + + if ((new_domain->u.file.server_info.password = RV_malloc(strlen(server_info->password) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't allocate space for copied password"); + + strcpy(new_domain->u.file.server_info.password, server_info->password); + + if ((new_domain->u.file.server_info.base_URL = RV_malloc(strlen(server_info->base_URL) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't allocate space for copied URL"); + + strcpy(new_domain->u.file.server_info.base_URL, server_info->base_URL); - new_domain->u.file.intent = loc_info_out->domain->u.file.intent; - new_domain->u.file.fapl_id = H5Pcopy(loc_info_out->domain->u.file.fapl_id); - new_domain->u.file.fcpl_id = H5Pcopy(loc_info_out->domain->u.file.fcpl_id); - new_domain->u.file.ref_count = 1; - new_domain->u.file.server_version = found_domain.u.file.server_version; + new_domain->u.file.intent = loc_info_out->domain->u.file.intent; + new_domain->u.file.fapl_id = H5Pcopy(loc_info_out->domain->u.file.fapl_id); + new_domain->u.file.fcpl_id = H5Pcopy(loc_info_out->domain->u.file.fcpl_id); + new_domain->u.file.ref_count = 1; + new_domain->u.file.server_info.version = found_domain.u.file.server_info.version; /* Allocate root "path" on heap for consistency with other RV_object_t types */ if ((new_domain->handle_path = RV_malloc(2)) == NULL) @@ -2537,7 +2526,7 @@ RV_copy_object_loc_info_callback(char *HTTP_response, void *callback_data_in, vo /* Assume that original domain and external domain have the same server version. * This will always be true unless it becomes possible for external links to point to * objects on different servers entirely. */ - memcpy(&new_domain->u.file.server_version, &loc_info_out->domain->u.file.server_version, + memcpy(&new_domain->u.file.server_info.version, &loc_info_out->domain->u.file.server_info.version, sizeof(server_api_version)); if (RV_file_close(loc_info_out->domain, H5P_DEFAULT, NULL) < 0) diff --git a/src/rest_vol.h b/src/rest_vol.h index 656aa734..b151e6a0 100644 --- a/src/rest_vol.h +++ b/src/rest_vol.h @@ -375,11 +375,6 @@ extern struct curl_slist *curl_headers; */ #define CURL_RESPONSE_BUFFER_DEFAULT_SIZE 1024 -/* - * Saved copy of the base URL for operating on - */ -extern char *base_URL; - #ifdef RV_TRACK_MEM_USAGE /* * Counter to keep track of the currently allocated amount of bytes @@ -502,6 +497,15 @@ typedef struct { size_t patch; } server_api_version; +/* Structure containing information to connect to and evaluate + * features of a server */ +typedef struct server_info_t { + char *username; + char *password; + char *base_URL; + server_api_version version; +} server_info_t; + /* * Definitions for the basic objects which the REST VOL uses * to represent various HDF5 objects internally. The base object @@ -511,12 +515,12 @@ typedef struct { typedef struct RV_object_t RV_object_t; typedef struct RV_file_t { - unsigned intent; - unsigned ref_count; - char *filepath_name; - hid_t fcpl_id; - hid_t fapl_id; - server_api_version server_version; + unsigned intent; + unsigned ref_count; + char *filepath_name; + server_info_t server_info; + hid_t fcpl_id; + hid_t fapl_id; } RV_file_t; typedef struct RV_group_t { @@ -677,8 +681,8 @@ typedef enum { extern "C" { #endif -/* Function to set the connection information for the connector to connect to the server */ -herr_t H5_rest_set_connection_information(void); +/* Function to set the connection information on a file for the connector to connect to the server */ +herr_t H5_rest_set_connection_information(server_info_t *server_info); /* Alternate, more portable version of the basename function which doesn't modify its argument */ const char *H5_rest_basename(const char *path); diff --git a/src/rest_vol_attr.c b/src/rest_vol_attr.c index 6952db93..5e8692e5 100644 --- a/src/rest_vol_attr.c +++ b/src/rest_vol_attr.c @@ -68,6 +68,7 @@ RV_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_ char *url_encoded_attr_name = NULL; int create_request_body_len = 0; int url_len = 0; + const char *base_URL = NULL; void *ret_value = NULL; #ifdef RV_CONNECTOR_DEBUG @@ -97,6 +98,9 @@ RV_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_ H5I_DATASET != parent->obj_type) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "parent object not a file, group, datatype or dataset"); + if ((base_URL = parent->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "parent object does not have valid server URL"); + /* Check for write access */ if (!(parent->domain->u.file.intent & H5F_ACC_RDWR)) FUNC_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "no write intent on file"); @@ -171,7 +175,7 @@ RV_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_ /* See HSDS#223 */ if ((H5I_DATATYPE == new_attribute->u.attribute.parent_obj_type) && - !(SERVER_VERSION_MATCHES_OR_EXCEEDS(parent->domain->u.file.server_version, 0, 8, 0))) + !(SERVER_VERSION_MATCHES_OR_EXCEEDS(parent->domain->u.file.server_info.version, 0, 8, 0))) FUNC_GOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, NULL, "server versions before 0.8.0 cannot properly create attributes on datatypes"); @@ -328,6 +332,12 @@ RV_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_ uinfo.buffer_size = (size_t)create_request_body_len; uinfo.bytes_sent = 0; + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, new_attribute->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, new_attribute->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_UPLOAD, 1)) @@ -433,6 +443,7 @@ RV_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_na char request_url[URL_MAX_LENGTH]; char *url_encoded_attr_name = NULL; const char *parent_obj_type_header = NULL; + const char *base_URL = NULL; int url_len = 0; void *ret_value = NULL; @@ -466,6 +477,9 @@ RV_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_na H5I_DATASET != parent->obj_type) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "parent object not a file, group, datatype or dataset"); + if ((base_URL = parent->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "parent object does not have valid server URL"); + if (aapl_id == H5I_INVALID_HID) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid AAPL"); @@ -554,7 +568,8 @@ RV_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_na switch (loc_params->loc_data.loc_by_idx.idx_type) { case (H5_INDEX_CRT_ORDER): - if (SERVER_VERSION_MATCHES_OR_EXCEEDS(parent->domain->u.file.server_version, 0, 8, 0)) { + if (SERVER_VERSION_MATCHES_OR_EXCEEDS(parent->domain->u.file.server_info.version, 0, 8, + 0)) { request_idx_type = "&CreateOrder=1"; } else { @@ -624,6 +639,12 @@ RV_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_na FUNC_GOTO_ERROR(H5E_ATTR, H5E_SYSERRSTR, NULL, "attribute open URL exceeded maximum URL size"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, attribute->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, attribute->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) @@ -708,6 +729,10 @@ RV_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_na printf("-> URL for attribute open request: %s\n\n", request_url); #endif + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, attribute->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, attribute->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) @@ -824,6 +849,7 @@ RV_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t dxpl_id, void **req) char *host_header = NULL; char *url_encoded_attr_name = NULL; char request_url[URL_MAX_LENGTH]; + const char *base_URL = NULL; int url_len = 0; herr_t ret_value = SUCCEED; @@ -840,6 +866,9 @@ RV_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t dxpl_id, void **req) if (!buf) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "read buffer was NULL"); + if ((base_URL = attribute->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "attribute does not have valid server URL"); + /* Determine whether it's possible to receive the data as a binary blob instead of as JSON */ if (H5T_NO_CLASS == (dtype_class = H5Tget_class(dtype_id))) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "memory datatype is invalid"); @@ -948,6 +977,10 @@ RV_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t dxpl_id, void **req) printf("-> URL for attribute read request: %s\n\n", request_url); #endif + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, attribute->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, attribute->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) @@ -1014,6 +1047,7 @@ RV_attr_write(void *attr, hid_t dtype_id, const void *buf, hid_t dxpl_id, void * char *host_header = NULL; char *url_encoded_attr_name = NULL; char request_url[URL_MAX_LENGTH]; + const char *base_URL = NULL; int url_len = 0; herr_t ret_value = SUCCEED; @@ -1030,6 +1064,9 @@ RV_attr_write(void *attr, hid_t dtype_id, const void *buf, hid_t dxpl_id, void * if (!buf) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "write buffer was NULL"); + if ((base_URL = attribute->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "attribute does not have valid server URL"); + /* Check for write access */ if (!(attribute->domain->u.file.intent & H5F_ACC_RDWR)) FUNC_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "no write intent on file"); @@ -1156,6 +1193,11 @@ RV_attr_write(void *attr, hid_t dtype_id, const void *buf, hid_t dxpl_id, void * uinfo.buffer_size = write_body_len; uinfo.bytes_sent = 0; + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, attribute->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, attribute->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_UPLOAD, 1)) @@ -1228,6 +1270,7 @@ RV_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) int url_len = 0; const char *parent_obj_type_header = NULL; const char *request_idx_type = NULL; + const char *base_URL = NULL; herr_t ret_value = SUCCEED; #ifdef RV_CONNECTOR_DEBUG @@ -1240,6 +1283,9 @@ RV_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent object not an attribute, file, group, datatype or dataset"); + if ((base_URL = loc_obj->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "location object does not have valid server URL"); + switch (args->op_type) { /* H5Aget_create_plist */ case H5VL_ATTR_GET_ACPL: { @@ -1444,8 +1490,8 @@ RV_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) switch (loc_params->loc_data.loc_by_idx.idx_type) { case (H5_INDEX_CRT_ORDER): - if (SERVER_VERSION_MATCHES_OR_EXCEEDS(loc_obj->domain->u.file.server_version, 0, - 8, 0)) { + if (SERVER_VERSION_MATCHES_OR_EXCEEDS(loc_obj->domain->u.file.server_info.version, + 0, 8, 0)) { request_idx_type = "&CreateOrder=1"; } else { @@ -1503,7 +1549,14 @@ RV_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) if (url_len >= URL_MAX_LENGTH) FUNC_GOTO_ERROR(H5E_ATTR, H5E_SYSERRSTR, FAIL, "attribute open URL exceeded maximum URL size"); - + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, + loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL username: %s", + curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, + loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL password: %s", + curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); @@ -1568,6 +1621,12 @@ RV_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) @@ -1643,8 +1702,8 @@ RV_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) switch (loc_params->loc_data.loc_by_idx.idx_type) { case (H5_INDEX_CRT_ORDER): - if (SERVER_VERSION_MATCHES_OR_EXCEEDS(loc_obj->domain->u.file.server_version, 0, - 7, 3)) { + if (SERVER_VERSION_MATCHES_OR_EXCEEDS(loc_obj->domain->u.file.server_info.version, + 0, 7, 3)) { request_idx_type = "&CreateOrder=1"; } else { @@ -1699,6 +1758,14 @@ RV_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) FUNC_GOTO_ERROR(H5E_ATTR, H5E_SYSERRSTR, FAIL, "attribute open URL exceeded maximum URL size"); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, + loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL username: %s", + curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, + loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL password: %s", + curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); @@ -1839,6 +1906,7 @@ RV_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_speci char attr_name_to_delete[ATTRIBUTE_NAME_MAX_LENGTH]; char *url_encoded_attr_name = NULL; const char *parent_obj_type_header = NULL; + const char *base_URL = NULL; int url_len = 0; herr_t ret_value = SUCCEED; @@ -1851,6 +1919,9 @@ RV_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_speci H5I_DATATYPE != loc_obj->obj_type && H5I_DATASET != loc_obj->obj_type) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent object not a file, group, datatype or dataset"); + if ((base_URL = loc_obj->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "location object does not have valid server URL"); + switch (args->op_type) { /* H5Adelete (_by_name/_by_idx) */ case H5VL_ATTR_DELETE_BY_IDX: { @@ -1919,6 +1990,12 @@ RV_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_speci /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE")) @@ -2089,7 +2166,12 @@ RV_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_speci /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); - + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE")) @@ -2251,6 +2333,12 @@ RV_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_speci /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) @@ -2338,7 +2426,7 @@ RV_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_speci switch (parent_obj_type) { case H5I_FILE: - /* Copy fapl, fcpl, and filepath name to new object */ + /* Copy plists, filepath, and server info to new object */ /* FAPL */ if (loc_obj->u.file.fapl_id != H5P_FILE_ACCESS_DEFAULT) { @@ -2362,11 +2450,38 @@ RV_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_speci if (NULL == (attr_iter_obj->u.file.filepath_name = RV_malloc(strlen(loc_obj->u.file.filepath_name) + 1))) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, - "can't allocate space for copied filepath_name object"); + "can't allocate space for copied filepath"); strncpy(attr_iter_obj->u.file.filepath_name, loc_obj->u.file.filepath_name, strlen(loc_obj->u.file.filepath_name) + 1); + if ((attr_iter_obj->u.file.server_info.username = + RV_malloc(strlen(loc_obj->u.file.server_info.username) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, + "can't allocate space for copied username"); + + strncpy(attr_iter_obj->u.file.server_info.username, + loc_obj->u.file.server_info.username, + strlen(loc_obj->u.file.server_info.username) + 1); + + if ((attr_iter_obj->u.file.server_info.password = + RV_malloc(strlen(loc_obj->u.file.server_info.password) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, + "can't allocate space for copied password"); + + strncpy(attr_iter_obj->u.file.server_info.password, + loc_obj->u.file.server_info.password, + strlen(loc_obj->u.file.server_info.password) + 1); + + if ((attr_iter_obj->u.file.server_info.base_URL = + RV_malloc(strlen(loc_obj->u.file.server_info.base_URL) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, + "can't allocate space for copied URL"); + + strncpy(attr_iter_obj->u.file.server_info.base_URL, + loc_obj->u.file.server_info.base_URL, + strlen(loc_obj->u.file.server_info.base_URL) + 1); + /* This is a copy of the file, not a reference to the same memory */ loc_obj->domain->u.file.ref_count--; break; @@ -2661,7 +2776,12 @@ RV_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_speci /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); - + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) diff --git a/src/rest_vol_config.h.in b/src/rest_vol_config.h.in index 5e0997d4..fe6e7dca 100644 --- a/src/rest_vol_config.h.in +++ b/src/rest_vol_config.h.in @@ -126,13 +126,13 @@ /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif +#if defined __BIG_ENDIAN__ +#define WORDS_BIGENDIAN 1 +#endif #else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif +#ifndef WORDS_BIGENDIAN +#undef WORDS_BIGENDIAN +#endif #endif /* Define to empty if `const' does not conform to ANSI C. */ diff --git a/src/rest_vol_dataset.c b/src/rest_vol_dataset.c index a309071f..7019f306 100644 --- a/src/rest_vol_dataset.c +++ b/src/rest_vol_dataset.c @@ -140,6 +140,7 @@ RV_dataset_create(void *obj, const H5VL_loc_params_t *loc_params, const char *na char *host_header = NULL; char *create_request_body = NULL; char request_url[URL_MAX_LENGTH]; + const char *base_URL = NULL; int url_len = 0; void *ret_value = NULL; @@ -157,6 +158,8 @@ RV_dataset_create(void *obj, const H5VL_loc_params_t *loc_params, const char *na if (H5I_FILE != parent->obj_type && H5I_GROUP != parent->obj_type) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "parent object not a file or group"); + if ((base_URL = parent->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "parent object does not have valid server URL"); /* Check for write access */ if (!(parent->domain->u.file.intent & H5F_ACC_RDWR)) @@ -251,6 +254,12 @@ RV_dataset_create(void *obj, const H5VL_loc_params_t *loc_params, const char *na printf("-> Dataset creation request URL: %s\n\n", request_url); #endif + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, new_dataset->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, new_dataset->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_POST, 1)) @@ -393,8 +402,8 @@ RV_dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name loc_info_out.GCPL_base64 = NULL; /* Locate dataset and set domain */ - search_ret = RV_find_object_by_path(parent, name, &obj_type, RV_copy_object_loc_info_callback, NULL, - &loc_info_out); + search_ret = RV_find_object_by_path(parent, name, &obj_type, RV_copy_object_loc_info_callback, + &dataset->domain->u.file.server_info, &loc_info_out); if (!search_ret || search_ret < 0) FUNC_GOTO_ERROR(H5E_DATASET, H5E_PATH, NULL, "can't locate dataset by path"); @@ -676,7 +685,8 @@ RV_dataset_read(size_t count, void *dset[], hid_t mem_type_id[], hid_t _mem_spac /* Redirect cURL from the base URL to "/datasets//value" to get the dataset data values */ if ((url_len = snprintf(transfer_info[i].request_url, URL_MAX_LENGTH, "%s/datasets/%s/value%s%s", - base_URL, transfer_info[i].dataset->URI, + transfer_info[i].dataset->domain->u.file.server_info.base_URL, + transfer_info[i].dataset->URI, is_transfer_binary && transfer_info[i].selection_body && (H5S_SEL_POINTS != transfer_info[i].u.read_info.sel_type) ? "?select=" @@ -1120,8 +1130,8 @@ RV_dataset_write(size_t count, void *dset[], hid_t mem_type_id[], hid_t _mem_spa /* Redirect cURL from the base URL to "/datasets//value" to write the value out */ if ((url_len = snprintf( - transfer_info[i].request_url, URL_MAX_LENGTH, "%s/datasets/%s/value%s%s", base_URL, - transfer_info[i].dataset->URI, + transfer_info[i].request_url, URL_MAX_LENGTH, "%s/datasets/%s/value%s%s", + transfer_info[i].dataset->domain->u.file.server_info.base_URL, transfer_info[i].dataset->URI, is_transfer_binary && selection_body && (H5S_SEL_POINTS != sel_type) ? "?select=" : "", is_transfer_binary && selection_body && (H5S_SEL_POINTS != sel_type) ? selection_body : "")) < 0) @@ -1316,6 +1326,7 @@ RV_dataset_get(void *obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **r size_t host_header_len = 0; char *host_header = NULL; char request_url[URL_MAX_LENGTH]; + const char *base_URL = NULL; #ifdef RV_CONNECTOR_DEBUG printf("-> Received dataset get call with following parameters:\n"); @@ -1327,6 +1338,8 @@ RV_dataset_get(void *obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **r if (H5I_DATASET != dset->obj_type) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a dataset"); + if ((base_URL = dset->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataset does not have valid server URL"); switch (args->op_type) { /* H5Dget_access_plist */ @@ -1367,7 +1380,7 @@ RV_dataset_get(void *obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **r /* H5Dget_storage_size */ case H5VL_DATASET_GET_STORAGE_SIZE: - if (!(SERVER_VERSION_SUPPORTS_GET_STORAGE_SIZE(dset->domain->u.file.server_version))) + if (!(SERVER_VERSION_SUPPORTS_GET_STORAGE_SIZE(dset->domain->u.file.server_info.version))) FUNC_GOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "H5Dget_storage_size requires HSDS 0.8.5 or higher"); @@ -1398,6 +1411,12 @@ RV_dataset_get(void *obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **r /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, dset->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, dset->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); @@ -1599,8 +1618,8 @@ RV_dataset_specific(void *obj, H5VL_dataset_specific_args_t *args, hid_t dxpl_id if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); - if ((url_len = - snprintf(request_url, URL_MAX_LENGTH, "%s/datasets/%s/shape", base_URL, dset->URI)) < 0) + if ((url_len = snprintf(request_url, URL_MAX_LENGTH, "%s/datasets/%s/shape", + dset->domain->u.file.server_info.base_URL, dset->URI)) < 0) FUNC_GOTO_ERROR(H5E_DATASET, H5E_SYSERRSTR, FAIL, "snprintf error"); if (url_len >= URL_MAX_LENGTH) @@ -3597,13 +3616,13 @@ RV_setup_dataset_create_request_body(void *parent_obj, const char *name, hid_t t * Dataset create request */ if (H5P_DATASET_CREATE_DEFAULT != dcpl) { if ((H5Pget_layout(dcpl) == H5D_CONTIGUOUS) && - !(SERVER_VERSION_MATCHES_OR_EXCEEDS(pobj->domain->u.file.server_version, 0, 8, 0))) + !(SERVER_VERSION_MATCHES_OR_EXCEEDS(pobj->domain->u.file.server_info.version, 0, 8, 0))) FUNC_GOTO_ERROR(H5E_PLIST, H5E_UNSUPPORTED, FAIL, "layout H5D_CONTIGUOUS is unsupported for server versions before 0.8.0"); if (RV_convert_dataset_creation_properties_to_JSON(dcpl, &creation_properties_body, &creation_properties_body_len, type_id, - pobj->domain->u.file.server_version) < 0) + pobj->domain->u.file.server_info.version) < 0) FUNC_GOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "can't convert Dataset Creation Properties to JSON representation"); } diff --git a/src/rest_vol_datatype.c b/src/rest_vol_datatype.c index cd452747..86e34bf2 100644 --- a/src/rest_vol_datatype.c +++ b/src/rest_vol_datatype.c @@ -74,6 +74,7 @@ RV_datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const char *n size_t datatype_body_len = 0; size_t path_size = 0; size_t path_len = 0; + const char *base_URL = NULL; char *host_header = NULL; char *commit_request_body = NULL; char *datatype_body = NULL; @@ -102,6 +103,9 @@ RV_datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const char *n if (H5I_FILE != parent->obj_type && H5I_GROUP != parent->obj_type) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "parent object not a file or group"); + if ((base_URL = parent->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "parent object does not have valid server URL"); + /* Check for write access */ if (!(parent->domain->u.file.intent & H5F_ACC_RDWR)) FUNC_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "no write intent on file"); @@ -255,6 +259,12 @@ RV_datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const char *n printf("-> Datatype commit URL: %s\n\n", request_url); #endif + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, new_datatype->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, NULL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, new_datatype->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, NULL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, NULL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_POST, 1)) @@ -393,8 +403,8 @@ RV_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const char *nam loc_info_out.GCPL_base64 = NULL; /* Locate datatype and set domain */ - search_ret = RV_find_object_by_path(parent, name, &obj_type, RV_copy_object_loc_info_callback, NULL, - &loc_info_out); + search_ret = RV_find_object_by_path(parent, name, &obj_type, RV_copy_object_loc_info_callback, + &datatype->domain->u.file.server_info, &loc_info_out); if (!search_ret || search_ret < 0) FUNC_GOTO_ERROR(H5E_DATATYPE, H5E_PATH, NULL, "can't locate datatype by path"); diff --git a/src/rest_vol_file.c b/src/rest_vol_file.c index a12c9b9d..d0056d50 100644 --- a/src/rest_vol_file.c +++ b/src/rest_vol_file.c @@ -70,9 +70,6 @@ RV_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, h printf(" - Default FAPL? %s\n\n", (H5P_FILE_ACCESS_DEFAULT == fapl_id) ? "yes" : "no"); #endif - if (H5_rest_set_connection_information() < 0) - FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't set REST VOL connector connection information"); - if (fapl_id == H5I_INVALID_HID) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid FAPL"); @@ -80,6 +77,9 @@ RV_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, h if (NULL == (new_file = (RV_object_t *)RV_malloc(sizeof(*new_file)))) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate space for file object"); + if (H5_rest_set_connection_information(&new_file->u.file.server_info) < 0) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't set REST VOL connector connection information"); + new_file->URI[0] = '\0'; new_file->obj_type = H5I_FILE; new_file->u.file.intent = H5F_ACC_RDWR; @@ -143,9 +143,13 @@ RV_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, h /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, new_file->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, new_file->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set cURL HTTP headers: %s", curl_err_buf); - if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_URL, base_URL)) + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_URL, new_file->u.file.server_info.base_URL)) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set cURL request URL: %s", curl_err_buf); /* Before making the actual request, check the file creation flags for @@ -262,7 +266,7 @@ RV_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, h FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, "can't parse new file's URI"); /* Store server version */ - if (RV_parse_response(response_buffer.buffer, NULL, &new_file->u.file.server_version, + if (RV_parse_response(response_buffer.buffer, NULL, &new_file->u.file.server_info.version, RV_parse_server_version) < 0) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, "can't parse server version"); @@ -343,9 +347,6 @@ RV_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, voi printf(" - Default FAPL? %s\n\n", (H5P_FILE_ACCESS_DEFAULT == fapl_id) ? "yes" : "no"); #endif - if (H5_rest_set_connection_information() < 0) - FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't set REST VOL connector connection information"); - if (fapl_id == H5I_INVALID_HID) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid FAPL"); @@ -353,6 +354,9 @@ RV_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, voi if (NULL == (file = (RV_object_t *)RV_malloc(sizeof(*file)))) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate space for file object"); + if (H5_rest_set_connection_information(&file->u.file.server_info) < 0) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't set REST VOL connector connection information"); + file->URI[0] = '\0'; file->obj_type = H5I_FILE; file->u.file.intent = flags; @@ -392,13 +396,17 @@ RV_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, voi /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, file->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, file->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set cURL password: %s", curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_URL, file->u.file.server_info.base_URL)) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set cURL request URL: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set up cURL to make HTTP GET request: %s", curl_err_buf); - if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_URL, base_URL)) - FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set cURL request URL: %s", curl_err_buf); #ifdef RV_CONNECTOR_DEBUG printf("-> Retrieving info for file open\n\n"); @@ -415,7 +423,7 @@ RV_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, voi FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't parse file's URI"); /* Store server version */ - if (RV_parse_response(response_buffer.buffer, NULL, &file->u.file.server_version, + if (RV_parse_response(response_buffer.buffer, NULL, &file->u.file.server_info.version, RV_parse_server_version) < 0) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, "can't parse server version"); @@ -662,14 +670,15 @@ RV_file_get(void *obj, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req) herr_t RV_file_specific(void *obj, H5VL_file_specific_args_t *args, hid_t dxpl_id, void **req) { - RV_object_t *file = (RV_object_t *)obj; - herr_t ret_value = SUCCEED; - size_t host_header_len; - size_t name_length; - long http_response; - char *host_header = NULL; - const char *filename = NULL; - char *request_url = NULL; + RV_object_t *file = (RV_object_t *)obj; + herr_t ret_value = SUCCEED; + size_t host_header_len; + size_t name_length; + long http_response; + char *host_header = NULL; + const char *filename = NULL; + char *request_url = NULL; + server_info_t *server_info = NULL; #ifdef RV_CONNECTOR_DEBUG printf("-> Received file-specific call with following parameters:\n"); @@ -709,11 +718,17 @@ RV_file_specific(void *obj, H5VL_file_specific_args_t *args, hid_t dxpl_id, void /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); - if (NULL == (request_url = (char *)RV_malloc(strlen(flush_string) + strlen(base_URL) + 1))) + if (NULL == (request_url = (char *)RV_malloc( + strlen(flush_string) + strlen(target_domain->u.file.server_info.base_URL) + 1))) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't allocate space for request URL"); - snprintf(request_url, URL_MAX_LENGTH, "%s%s", base_URL, flush_string); + snprintf(request_url, URL_MAX_LENGTH, "%s%s", target_domain->u.file.server_info.base_URL, + flush_string); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, file->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, file->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_URL, request_url)) @@ -794,9 +809,22 @@ RV_file_specific(void *obj, H5VL_file_specific_args_t *args, hid_t dxpl_id, void /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + /* H5Fdelete doesn't receive a file handle, so the username/password must be pulled + * from environment for now */ + if ((server_info = RV_calloc(sizeof(server_info_t))) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't allocate space for server information"); + + if (H5_rest_set_connection_information(server_info) < 0) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get server connection information"); + + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, server_info->username)) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, server_info->password)) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); - if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_URL, base_URL)) + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_URL, server_info->base_URL)) FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set cURL request URL: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE")) @@ -836,6 +864,13 @@ RV_file_specific(void *obj, H5VL_file_specific_args_t *args, hid_t dxpl_id, void if (request_url) RV_free(request_url); + if (server_info) { + RV_free(server_info->base_URL); + RV_free(server_info->username); + RV_free(server_info->password); + RV_free(server_info); + } + return ret_value; } /* end RV_file_specific() */ @@ -890,10 +925,16 @@ RV_file_close(void *file, hid_t dxpl_id, void **req) _file->u.file.filepath_name = NULL; } - if (_file->handle_path) { - RV_free(_file->handle_path); - _file->handle_path = NULL; - } + RV_free(_file->u.file.server_info.username); + RV_free(_file->u.file.server_info.password); + RV_free(_file->u.file.server_info.base_URL); + + _file->u.file.server_info.username = NULL; + _file->u.file.server_info.password = NULL; + _file->u.file.server_info.base_URL = NULL; + + RV_free(_file->handle_path); + _file->handle_path = NULL; if (RV_type_info_array_g[H5I_FILE]) rv_hash_table_remove(RV_type_info_array_g[H5I_FILE]->table, (char *)_file->URI); diff --git a/src/rest_vol_group.c b/src/rest_vol_group.c index 01d06007..c17879ae 100644 --- a/src/rest_vol_group.c +++ b/src/rest_vol_group.c @@ -49,6 +49,7 @@ RV_group_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name size_t plist_nalloc = 0; size_t path_size = 0; size_t path_len = 0; + const char *base_URL = NULL; char *host_header = NULL; char *create_request_body = NULL; char *path_dirname = NULL; @@ -75,6 +76,9 @@ RV_group_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name if (H5I_FILE != parent->obj_type && H5I_GROUP != parent->obj_type) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "parent object not a file or group"); + if ((base_URL = parent->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "parent object does not have valid server URL"); + if (gapl_id == H5I_INVALID_HID) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid GAPL"); @@ -252,6 +256,10 @@ RV_group_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name printf("-> Group create request URL: %s\n\n", request_url); #endif + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, new_group->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTSET, NULL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, new_group->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTSET, NULL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTSET, NULL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_POST, 1)) @@ -399,8 +407,8 @@ RV_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, loc_info_out.domain = group->domain; loc_info_out.GCPL_base64 = NULL; - search_ret = RV_find_object_by_path(parent, name, &obj_type, RV_copy_object_loc_info_callback, NULL, - &loc_info_out); + search_ret = RV_find_object_by_path(parent, name, &obj_type, RV_copy_object_loc_info_callback, + &group->domain->u.file.server_info, &loc_info_out); if (!search_ret || search_ret < 0) FUNC_GOTO_ERROR(H5E_SYM, H5E_PATH, NULL, "can't locate group by path"); @@ -411,7 +419,7 @@ RV_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, #endif /* Decode creation properties, if server supports them and file has them */ - if (SERVER_VERSION_MATCHES_OR_EXCEEDS(parent->domain->u.file.server_version, 0, 8, 0) && + if (SERVER_VERSION_MATCHES_OR_EXCEEDS(parent->domain->u.file.server_info.version, 0, 8, 0) && loc_info_out.GCPL_base64) { if (RV_base64_decode(loc_info_out.GCPL_base64, strlen(loc_info_out.GCPL_base64), (char **)&binary_gcpl, binary_gcpl_size) < 0) @@ -489,6 +497,7 @@ RV_group_get(void *obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req) char *host_header = NULL; char request_url[URL_MAX_LENGTH]; int url_len = 0; + const char *base_URL = NULL; herr_t ret_value = SUCCEED; loc_info loc_info_out; @@ -501,6 +510,8 @@ RV_group_get(void *obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req) if (H5I_FILE != loc_obj->obj_type && H5I_GROUP != loc_obj->obj_type) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a group"); + if ((base_URL = loc_obj->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent object does not have valid server URL"); switch (args->op_type) { /* H5Gget_create_plist */ @@ -561,9 +572,9 @@ RV_group_get(void *obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req) loc_info_out.domain = loc_obj->domain; loc_info_out.GCPL_base64 = NULL; - search_ret = - RV_find_object_by_path(loc_obj, loc_params->loc_data.loc_by_name.name, &obj_type, - RV_copy_object_loc_info_callback, NULL, &loc_info_out); + search_ret = RV_find_object_by_path(loc_obj, loc_params->loc_data.loc_by_name.name, + &obj_type, RV_copy_object_loc_info_callback, + &loc_obj->domain->u.file.server_info, &loc_info_out); if (!search_ret || search_ret < 0) FUNC_GOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't locate group"); @@ -618,6 +629,12 @@ RV_group_get(void *obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req) /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) diff --git a/src/rest_vol_link.c b/src/rest_vol_link.c index 2ee54e45..32a486e2 100644 --- a/src/rest_vol_link.c +++ b/src/rest_vol_link.c @@ -31,7 +31,8 @@ static herr_t RV_link_iter_callback(char *HTTP_response, void *callback_data_in, /* Helper functions to work with a table of links for link iteration */ static herr_t RV_build_link_table(char *HTTP_response, hbool_t is_recursive, int (*sort_func)(const void *, const void *), link_table_entry **link_table, - size_t *num_entries, rv_hash_table_t *visited_link_table); + size_t *num_entries, rv_hash_table_t *visited_link_table, + const char *base_URL); static void RV_free_link_table(link_table_entry *link_table, size_t num_entries); static herr_t RV_traverse_link_table(link_table_entry *link_table, size_t num_entries, iter_data *iter_data, const char *cur_link_rel_path); @@ -74,6 +75,7 @@ RV_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t size_t create_request_nalloc = 0; size_t host_header_len = 0; void *hard_link_target_obj; + const char *base_URL = NULL; char *host_header = NULL; char *create_request_body = NULL; char request_url[URL_MAX_LENGTH]; @@ -94,7 +96,6 @@ RV_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t printf(" - Default LCPL? %s\n", (H5P_LINK_CREATE_DEFAULT == lcpl_id) ? "yes" : "no"); printf(" - Default LAPL? %s\n\n", (H5P_LINK_ACCESS_DEFAULT == lapl_id) ? "yes" : "no"); #endif - if (lcpl_id == H5I_INVALID_HID) FUNC_GOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "invalid LCPL"); @@ -120,6 +121,12 @@ RV_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t new_link_loc_obj = (RV_object_t *)hard_link_target_obj; } /* end if */ + if (!new_link_loc_obj) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link location object is NULL"); + + if ((base_URL = new_link_loc_obj->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link creation requires valid server URL"); + /* Validate loc_id and check for write access on the file */ if (H5I_FILE != new_link_loc_obj->obj_type && H5I_GROUP != new_link_loc_obj->obj_type) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link location object not a file or group"); @@ -336,7 +343,12 @@ RV_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t uinfo.buffer = create_request_body; uinfo.buffer_size = (size_t)create_request_body_len; uinfo.bytes_sent = 0; - + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, new_link_loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, new_link_loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_UPLOAD, 1)) @@ -462,6 +474,7 @@ RV_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t RV_object_t *loc_obj = (RV_object_t *)obj; hbool_t empty_dirname; size_t host_header_len = 0; + const char *base_URL = NULL; char *host_header = NULL; char *link_dir_name = NULL; char *url_encoded_link_name = NULL; @@ -478,6 +491,9 @@ RV_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t printf(" - Link loc_obj's domain path: %s\n\n", loc_obj->domain->u.file.filepath_name); #endif + if ((base_URL = loc_obj->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "location object does not have valid server URL"); + switch (args->op_type) { /* H5Lget_info */ case H5VL_LINK_GET_INFO: { @@ -565,7 +581,12 @@ RV_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); - + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) @@ -618,7 +639,7 @@ RV_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t by_idx_data.idx_p = &loc_params->loc_data.loc_by_idx.n; by_idx_data.iter_function.link_iter_op = NULL; by_idx_data.op_data = NULL; - + by_idx_data.iter_obj_parent = loc_obj; /* * Setup information to be passed back from link name retrieval callback */ @@ -658,6 +679,12 @@ RV_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) @@ -773,6 +800,12 @@ RV_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) @@ -844,6 +877,7 @@ RV_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_speci size_t host_header_len = 0; hid_t link_iter_group_id = H5I_INVALID_HID; void *link_iter_group_object = NULL; + const char *base_URL = NULL; char *host_header = NULL; char *link_path_dirname = NULL; char temp_URI[URI_MAX_LENGTH]; @@ -863,6 +897,9 @@ RV_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_speci if (H5I_FILE != loc_obj->obj_type && H5I_GROUP != loc_obj->obj_type) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent object not a file or group"); + if ((base_URL = loc_obj->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "location object does not have valid server URL"); + switch (args->op_type) { /* H5Ldelete */ case H5VL_LINK_DELETE: { @@ -942,6 +979,12 @@ RV_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_speci /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE")) @@ -1020,6 +1063,12 @@ RV_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_speci /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) @@ -1056,6 +1105,7 @@ RV_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_speci link_iter_data.idx_p = args->args.iterate.idx_p; link_iter_data.iter_function.link_iter_op = args->args.iterate.op; link_iter_data.op_data = args->args.iterate.op_data; + link_iter_data.iter_obj_parent = loc_obj; if (!link_iter_data.iter_function.link_iter_op) FUNC_GOTO_ERROR(H5E_LINK, H5E_LINKITERERROR, FAIL, "no link iteration function specified"); @@ -1165,6 +1215,12 @@ RV_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_speci /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) @@ -1626,7 +1682,8 @@ RV_get_link_name_by_idx_callback(char *HTTP_response, void *callback_data_in, vo #endif if (RV_build_link_table(HTTP_response, by_idx_data->is_recursive, link_table_sort_func, &link_table, - &link_table_num_entries, NULL) < 0) + &link_table_num_entries, NULL, + by_idx_data->iter_obj_parent->domain->u.file.server_info.base_URL) < 0) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTBUILDLINKTABLE, FAIL, "can't build link table"); /* Check to make sure the index given is within bounds */ @@ -1725,7 +1782,8 @@ RV_link_iter_callback(char *HTTP_response, void *callback_data_in, void *callbac */ if (RV_build_link_table(HTTP_response, link_iter_data->is_recursive, H5_rest_cmp_links_by_creation_order_inc, &link_table, &link_table_num_entries, - visited_link_table) < 0) + visited_link_table, + link_iter_data->iter_obj_parent->domain->u.file.server_info.base_URL) < 0) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTBUILDLINKTABLE, FAIL, "can't build link table"); #ifdef RV_CONNECTOR_DEBUG @@ -1734,7 +1792,8 @@ RV_link_iter_callback(char *HTTP_response, void *callback_data_in, void *callbac } /* end if */ else { if (RV_build_link_table(HTTP_response, link_iter_data->is_recursive, NULL, &link_table, - &link_table_num_entries, visited_link_table) < 0) + &link_table_num_entries, visited_link_table, + link_iter_data->iter_obj_parent->domain->u.file.server_info.base_URL) < 0) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTBUILDLINKTABLE, FAIL, "can't build link table"); } /* end else */ @@ -1787,7 +1846,8 @@ RV_link_iter_callback(char *HTTP_response, void *callback_data_in, void *callbac */ static herr_t RV_build_link_table(char *HTTP_response, hbool_t is_recursive, int (*sort_func)(const void *, const void *), - link_table_entry **link_table, size_t *num_entries, rv_hash_table_t *visited_link_table) + link_table_entry **link_table, size_t *num_entries, rv_hash_table_t *visited_link_table, + const char *base_URL) { link_table_entry *table = NULL; yajl_val parse_tree = NULL, key_obj; @@ -1984,7 +2044,7 @@ RV_build_link_table(char *HTTP_response, hbool_t is_recursive, int (*sort_func)( if (RV_build_link_table(response_buffer.buffer, is_recursive, sort_func, &table[i].subgroup.subgroup_link_table, - &table[i].subgroup.num_entries, visited_link_table) < 0) + &table[i].subgroup.num_entries, visited_link_table, base_URL) < 0) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTBUILDLINKTABLE, FAIL, "can't build link table for subgroup '%s'", table[i].link_name); diff --git a/src/rest_vol_object.c b/src/rest_vol_object.c index 756ed135..bc6d85e0 100644 --- a/src/rest_vol_object.c +++ b/src/rest_vol_object.c @@ -270,6 +270,7 @@ RV_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_ar char *host_header = NULL; char request_url[URL_MAX_LENGTH]; char *found_object_name = NULL; + const char *base_URL = NULL; int url_len = 0; herr_t ret_value = SUCCEED; loc_info loc_info_out; @@ -290,6 +291,9 @@ RV_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_ar H5I_DATATYPE != loc_obj->obj_type && H5I_DATASET != loc_obj->obj_type) FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file, group, dataset or committed datatype"); + if ((base_URL = loc_obj->domain->u.file.server_info.base_URL) == NULL) + FUNC_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "location object does not have valid server URL"); + switch (args->op_type) { case H5VL_OBJECT_GET_NAME: { size_t copy_size = 0; @@ -421,9 +425,9 @@ RV_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_ar /* loc_info_out.domain was copied at function start */ /* Locate group and set domain */ - search_ret = - RV_find_object_by_path(loc_obj, loc_params->loc_data.loc_by_name.name, &obj_type, - RV_copy_object_loc_info_callback, NULL, &loc_info_out); + search_ret = RV_find_object_by_path(loc_obj, loc_params->loc_data.loc_by_name.name, + &obj_type, RV_copy_object_loc_info_callback, + &loc_obj->domain->u.file.server_info, &loc_info_out); if (!search_ret || search_ret < 0) FUNC_GOTO_ERROR(H5E_OBJECT, H5E_PATH, FAIL, "can't locate object by path"); @@ -521,9 +525,9 @@ RV_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_ar /* loc_info_out.domain was copied at function start */ /* Locate group and set domain */ - search_ret = - RV_find_object_by_path(loc_obj, loc_params->loc_data.loc_by_name.name, &obj_type, - RV_copy_object_loc_info_callback, NULL, &loc_info_out); + search_ret = RV_find_object_by_path(loc_obj, loc_params->loc_data.loc_by_name.name, + &obj_type, RV_copy_object_loc_info_callback, + &loc_obj->domain->u.file.server_info, &loc_info_out); if (!search_ret || search_ret < 0) FUNC_GOTO_ERROR(H5E_OBJECT, H5E_PATH, FAIL, "can't locate object by path"); @@ -532,8 +536,8 @@ RV_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_ar switch (loc_params->loc_data.loc_by_idx.idx_type) { case (H5_INDEX_CRT_ORDER): - if (SERVER_VERSION_MATCHES_OR_EXCEEDS(loc_obj->domain->u.file.server_version, 0, - 8, 0)) { + if (SERVER_VERSION_MATCHES_OR_EXCEEDS(loc_obj->domain->u.file.server_info.version, + 0, 8, 0)) { request_idx_type = "&CreateOrder=1"; } else { @@ -580,6 +584,14 @@ RV_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_ar FUNC_GOTO_ERROR(H5E_LINK, H5E_SYSERRSTR, FAIL, "attribute open URL exceeded maximum URL size"); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_USERNAME, + loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL username: %s", + curl_err_buf); + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_PASSWORD, + loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL password: %s", + curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); @@ -614,9 +626,9 @@ RV_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_ar loc_info_out.GCPL_base64 = NULL; } - search_ret = - RV_find_object_by_path(loc_obj, found_object_name, &obj_type, - RV_copy_object_loc_info_callback, NULL, &loc_info_out); + search_ret = RV_find_object_by_path(loc_obj, found_object_name, &obj_type, + RV_copy_object_loc_info_callback, + &loc_obj->domain->u.file.server_info, &loc_info_out); if (!search_ret || search_ret < 0) FUNC_GOTO_ERROR(H5E_OBJECT, H5E_PATH, FAIL, "can't locate object by path"); @@ -657,6 +669,12 @@ RV_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_ar /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_OBJECT, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); @@ -827,7 +845,7 @@ RV_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_s /* Increment refs for specific type */ switch (loc_obj->obj_type) { case H5I_FILE: - /* Copy fapl, fcpl, and filepath name to new object */ + /* Copy plists, filepath, and server info to new object */ if (H5I_INVALID_HID == (iter_object->u.file.fapl_id = H5Pcopy(loc_obj->u.file.fapl_id))) @@ -843,6 +861,33 @@ RV_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_s strncpy(iter_object->u.file.filepath_name, loc_obj->u.file.filepath_name, strlen(loc_obj->u.file.filepath_name) + 1); + if ((iter_object->u.file.server_info.username = + RV_malloc(strlen(loc_obj->u.file.server_info.username) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, + "can't allocate space for copied username"); + + strncpy(iter_object->u.file.server_info.username, + loc_obj->u.file.server_info.username, + strlen(loc_obj->u.file.server_info.username) + 1); + + if ((iter_object->u.file.server_info.password = + RV_malloc(strlen(loc_obj->u.file.server_info.password) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, + "can't allocate space for copied password"); + + strncpy(iter_object->u.file.server_info.password, + loc_obj->u.file.server_info.password, + strlen(loc_obj->u.file.server_info.password) + 1); + + if ((iter_object->u.file.server_info.base_URL = + RV_malloc(strlen(loc_obj->u.file.server_info.base_URL) + 1)) == NULL) + FUNC_GOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, + "can't allocate space for copied URL"); + + strncpy(iter_object->u.file.server_info.base_URL, + loc_obj->u.file.server_info.base_URL, + strlen(loc_obj->u.file.server_info.base_URL) + 1); + /* This is a copy of the file, not a reference to the same memory */ loc_obj->domain->u.file.ref_count--; iter_object->u.file.ref_count = 1; @@ -996,8 +1041,9 @@ RV_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_s /* To build object table, information about parent object will be needed */ object_iter_data.iter_obj_parent = iter_object; - if ((url_len = snprintf(request_url, URL_MAX_LENGTH, "%s/%s/%s", base_URL, object_type_header, - object_iter_data.iter_obj_parent->URI)) < 0) + if (url_len = snprintf(request_url, URL_MAX_LENGTH, "%s/%s/%s", + iter_object->domain->u.file.server_info.base_URL, object_type_header, + object_iter_data.iter_obj_parent->URI) < 0) FUNC_GOTO_ERROR(H5E_LINK, H5E_SYSERRSTR, FAIL, "snprintf error"); if (url_len >= URL_MAX_LENGTH) @@ -1065,6 +1111,12 @@ RV_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_s /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_USERNAME, loc_obj->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL username: %s", curl_err_buf); + if (CURLE_OK != + curl_easy_setopt(curl, CURLOPT_PASSWORD, loc_obj->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL password: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPGET, 1)) @@ -1109,9 +1161,11 @@ RV_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_s switch (iter_object_type) { case H5I_FILE: case H5I_GROUP: - if ((url_len = snprintf(request_url, URL_MAX_LENGTH, "%s/%s/%s%s", base_URL, - object_type_header, object_iter_data.iter_obj_parent->URI, - (!strcmp(object_type_header, "groups") ? "/links" : ""))) < 0) + if (url_len = + snprintf(request_url, URL_MAX_LENGTH, "%s/%s/%s%s", + object_iter_data.iter_obj_parent->domain->u.file.server_info.base_URL, + object_type_header, object_iter_data.iter_obj_parent->URI, + (!strcmp(object_type_header, "groups") ? "/links" : "")) < 0) FUNC_GOTO_ERROR(H5E_LINK, H5E_SYSERRSTR, FAIL, "snprintf error"); if (url_len >= URL_MAX_LENGTH) @@ -1756,8 +1810,10 @@ RV_build_object_table(char *HTTP_response, hbool_t is_recursive, int (*sort_func curl, H5_rest_basename(YAJL_GET_STRING(link_field_obj)), 0))) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTENCODE, FAIL, "can't URL-encode link name"); - if ((url_len = snprintf(request_url, URL_MAX_LENGTH, "%s/groups/%s/links", base_URL, - url_encoded_link_name)) < 0) + if ((url_len = + snprintf(request_url, URL_MAX_LENGTH, "%s/groups/%s/links", + object_iter_data->iter_obj_parent->domain->u.file.server_info.base_URL, + url_encoded_link_name)) < 0) FUNC_GOTO_ERROR(H5E_LINK, H5E_SYSERRSTR, FAIL, "snprintf error"); if (url_len >= URL_MAX_LENGTH) @@ -1796,6 +1852,18 @@ RV_build_object_table(char *HTTP_response, hbool_t is_recursive, int (*sort_func /* Disable use of Expect: 100 Continue HTTP response */ curl_headers = curl_slist_append(curl_headers, "Expect:"); + if (CURLE_OK != + curl_easy_setopt( + curl, CURLOPT_USERNAME, + object_iter_data->iter_obj_parent->domain->u.file.server_info.username)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL username: %s", + curl_err_buf); + if (CURLE_OK != + curl_easy_setopt( + curl, CURLOPT_PASSWORD, + object_iter_data->iter_obj_parent->domain->u.file.server_info.password)) + FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL password: %s", + curl_err_buf); if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers)) FUNC_GOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set cURL HTTP headers: %s", curl_err_buf);