From db7be74b3da460496b5d3d2b612753a788d80d52 Mon Sep 17 00:00:00 2001 From: David Snopek Date: Sun, 4 Sep 2011 15:24:23 -0500 Subject: [PATCH 1/2] list_directory() will now request the next set of objects if it gets exactly 10k (the max returned per request per the Rackspace docs) --- cloudfsapi.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/cloudfsapi.c b/cloudfsapi.c index 0940da0..b71611e 100644 --- a/cloudfsapi.c +++ b/cloudfsapi.c @@ -16,6 +16,9 @@ #define REQUEST_RETRIES 4 +// defined by Rackspace +#define MAX_RESULTS_PER_REQUEST 10000 + static char storage_url[MAX_URL_SIZE]; static char storage_token[MAX_HEADER_SIZE]; static pthread_mutex_t pool_mut; @@ -230,13 +233,12 @@ int object_truncate(const char *path, off_t size) return (response >= 200 && response < 300); } -int list_directory(const char *path, dir_entry **dir_list) +int list_directory_internal(const char *path, dir_entry **dir_list) { char container[MAX_PATH_SIZE * 3] = ""; char object[MAX_PATH_SIZE] = ""; int response = 0; - int retval = 0; - *dir_list = NULL; + int retval = -1; xmlNode *onode = NULL, *anode = NULL, *text_node = NULL; xmlParserCtxtPtr xmlctx = xmlCreatePushParserCtxt(NULL, NULL, "", 0, NULL); if (!strcmp(path, "") || !strcmp(path, "/")) @@ -254,10 +256,16 @@ int list_directory(const char *path, dir_entry **dir_list) curl_free(encoded_container); curl_free(encoded_object); } + if (*dir_list != NULL) { + strcat(container, "&marker="); + strcat(container, (*dir_list)->name); + } + printf("%s\n", container); response = send_request("GET", container, NULL, xmlctx, NULL); xmlParseChunk(xmlctx, "", 0, 1); if (xmlctx->wellFormed && response >= 200 && response < 300) { + retval = 0; xmlNode *root_element = xmlDocGetRootElement(xmlctx->myDoc); for (onode = root_element->children; onode; onode = onode->next) if ((onode->type == XML_ELEMENT_NODE) && @@ -304,14 +312,26 @@ int list_directory(const char *path, dir_entry **dir_list) (strstr(de->content_type, "application/directory") != NULL)); de->next = *dir_list; *dir_list = de; + retval++; } - retval = 1; } xmlFreeDoc(xmlctx->myDoc); xmlFreeParserCtxt(xmlctx); return retval; } +int list_directory(const char *path, dir_entry **dir_list) +{ + int retval; + *dir_list = NULL; + + do { + retval = list_directory_internal(path, dir_list); + } while(retval == MAX_RESULTS_PER_REQUEST); + + return retval == -1 ? 0 : 1; +} + void free_dir_list(dir_entry *dir_list) { while (dir_list) From 10947d3467da0faee05cb28db9c2462fd597a140 Mon Sep 17 00:00:00 2001 From: Jay Terray Date: Sun, 3 Jun 2012 17:38:26 -0400 Subject: [PATCH 2/2] fixed marker problem when the last item is in a subdirectory --- cloudfsapi.c | 5 ++++- cloudfsapi.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cloudfsapi.c b/cloudfsapi.c index b71611e..1737827 100644 --- a/cloudfsapi.c +++ b/cloudfsapi.c @@ -4,7 +4,9 @@ #include #include #include +#ifdef __linux__ #include +#endif #include #include #include @@ -258,7 +260,7 @@ int list_directory_internal(const char *path, dir_entry **dir_list) } if (*dir_list != NULL) { strcat(container, "&marker="); - strcat(container, (*dir_list)->name); + strcat(container, (*dir_list)->marker); } printf("%s\n", container); response = send_request("GET", container, NULL, xmlctx, NULL); @@ -288,6 +290,7 @@ int list_directory_internal(const char *path, dir_entry **dir_list) de->name = strdup(strrchr(content, '/')+1); else de->name = strdup(content); + de->marker = strdup(content); if (asprintf(&(de->full_name), "%s/%s", path, de->name) < 0) de->full_name = NULL; } diff --git a/cloudfsapi.h b/cloudfsapi.h index 54a5871..2076bd8 100644 --- a/cloudfsapi.h +++ b/cloudfsapi.h @@ -21,6 +21,7 @@ typedef struct dir_entry time_t last_modified; int isdir; struct dir_entry *next; + char *marker; } dir_entry; int object_read_fp(const char *path, FILE *fp);