Skip to content

Commit 093465b

Browse files
committed
The error handling code is now collecting the contents of the error body.
1 parent 997e25c commit 093465b

File tree

2 files changed

+40
-15
lines changed

2 files changed

+40
-15
lines changed

sample/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ int main (int args, char * argv[]) {
2222
if(error != NULL) {
2323
if(error->error != NULL) {
2424
printf("Got an error (%lu): %s\n", error->error->status_code, error->message);
25+
printf("Message Body: %s\n", error->error->error_body);
2526
}
2627
else {
2728
printf("Got a runtime error: %s\n", error->message);

src/ds3.c

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,17 @@ typedef struct {
4747
}ds3_xml_send_buff;
4848

4949
typedef struct {
50+
// These attributes are used when processing a response header
5051
uint64_t status_code;
5152
char* status_message;
5253
size_t status_message_size;
5354
size_t header_count;
5455
GHashTable* headers;
55-
GByteArray* body; // this will only be used when getting errors
5656

57+
// These attributes are used when processing a response body
58+
GByteArray* body; // this will only be used when getting errors
5759
void* user_data;
60+
size_t (*user_func)(void*, size_t, size_t, void*);
5861
}ds3_response_data;
5962

6063
typedef struct {
@@ -101,6 +104,14 @@ static size_t _ds3_send_xml_buff(void* buffer, size_t size, size_t nmemb, void*
101104
return to_read;
102105
}
103106

107+
static size_t load_buffer(void* buffer, size_t size, size_t nmemb, void* user_data) {
108+
size_t realsize = size * nmemb;
109+
GByteArray* blob = (GByteArray*) user_data;
110+
111+
g_byte_array_append(blob, (const guint8 *) buffer, realsize);
112+
return realsize;
113+
}
114+
104115
static size_t _process_header_line(void* buffer, size_t size, size_t nmemb, void* user_data) {
105116
size_t to_read;
106117
char* header_buff;
@@ -181,6 +192,18 @@ static size_t _process_header_line(void* buffer, size_t size, size_t nmemb, void
181192
return to_read;
182193
}
183194

195+
static size_t _process_response_body(void* buffer, size_t size, size_t nmemb, void* user_data) {
196+
ds3_response_data* response_data = (ds3_response_data*) user_data;
197+
198+
// If we got an error, collect the error body
199+
if (response_data->status_code >= 400) {
200+
return load_buffer(buffer, size, nmemb, response_data->body);
201+
}
202+
else { // If we did not get an error, call he user's defined callbacks.
203+
return response_data->user_func(buffer, size, nmemb, response_data->user_data);
204+
}
205+
}
206+
184207
//---------- Networking code ----------//
185208
static void _init_curl(void) {
186209
static ds3_bool initialized = False;
@@ -283,7 +306,7 @@ static char* _net_gen_query_params(GHashTable* query_params) {
283306

284307
return_string = g_strjoinv("&", entries);
285308

286-
for(i= 0; ; i++ ) {
309+
for(i = 0; ; i++) {
287310
char* current_string = entries[i];
288311
if(current_string == NULL) {
289312
break;
@@ -319,8 +342,8 @@ static ds3_error* _net_process_request(const ds3_client* client, const ds3_reque
319342
GHashTable* response_headers = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, _ds3_free_response_header);
320343

321344
memset(&response_data, 0, sizeof(ds3_response_data));
322-
323345
response_data.headers = response_headers;
346+
response_data.body = g_byte_array_new();
324347

325348
if (query_params == NULL) {
326349
url = g_strconcat(client->endpoint, request->path, NULL);
@@ -343,10 +366,14 @@ static ds3_error* _net_process_request(const ds3_client* client, const ds3_reque
343366

344367
// Register the read and write handlers if they are set
345368
if(read_user_struct != NULL && read_handler_func != NULL) {
346-
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, read_handler_func);
347-
curl_easy_setopt(handle, CURLOPT_WRITEDATA, read_user_struct);
369+
response_data.user_data = read_user_struct;
370+
response_data.user_func = read_handler_func;
348371
}
349372

373+
// We must always set this so we can collect the error message body
374+
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, _process_response_body);
375+
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response_data);
376+
350377
if(write_user_struct != NULL && write_handler_func != NULL) {
351378
curl_easy_setopt(handle, CURLOPT_READFUNCTION, write_handler_func);
352379
curl_easy_setopt(handle, CURLOPT_READDATA, write_user_struct);
@@ -418,10 +445,14 @@ static ds3_error* _net_process_request(const ds3_client* client, const ds3_reque
418445
error->error->status_code = response_data.status_code;
419446
error->error->status_message = g_strdup(response_data.status_message);
420447
error->error->status_message_size = strlen(error->error->status_message);
448+
error->error->error_body = g_strdup(response_data.body->data);
449+
error->error->error_body_size = response_data.body->len;
421450

451+
g_byte_array_free(response_data.body, TRUE);
422452
g_free(response_data.status_message);
423453
return error;
424454
}
455+
g_byte_array_free(response_data.body, TRUE);
425456
g_free(response_data.status_message);
426457
if(res != CURLE_OK) {
427458
char * message = g_strconcat("Request failed: ", curl_easy_strerror(res), NULL);
@@ -579,13 +610,6 @@ static ds3_error* _internal_request_dispatcher(const ds3_client* client, const d
579610
return _net_process_request(client, request, read_user_struct, read_handler_func, write_user_struct, write_handler_func);
580611
}
581612

582-
static size_t load_xml_buff(void* contents, size_t size, size_t nmemb, void* user_data) {
583-
size_t realsize = size * nmemb;
584-
GByteArray* blob = (GByteArray*) user_data;
585-
586-
g_byte_array_append(blob, (const guint8 *) contents, realsize);
587-
return realsize;
588-
}
589613

590614
static void _parse_buckets(xmlDocPtr doc, xmlNodePtr buckets_node, ds3_get_service_response* response) {
591615
xmlChar* text;
@@ -656,7 +680,7 @@ ds3_error* ds3_get_service(const ds3_client* client, const ds3_request* request,
656680
ds3_error* error;
657681
GByteArray* xml_blob = g_byte_array_new();
658682

659-
error = _internal_request_dispatcher(client, request, xml_blob, load_xml_buff, NULL, NULL);
683+
error = _internal_request_dispatcher(client, request, xml_blob, load_buffer, NULL, NULL);
660684

661685
if(error != NULL) {
662686
g_byte_array_free(xml_blob, TRUE);
@@ -774,7 +798,7 @@ ds3_error* ds3_get_bucket(const ds3_client* client, const ds3_request* request,
774798
xmlChar* text;
775799
GArray* object_array = g_array_new(FALSE, TRUE, sizeof(ds3_object));
776800
GByteArray* xml_blob = g_byte_array_new();
777-
_internal_request_dispatcher(client, request, xml_blob, load_xml_buff, NULL, NULL);
801+
_internal_request_dispatcher(client, request, xml_blob, load_buffer, NULL, NULL);
778802

779803
doc = xmlParseMemory((const char*) xml_blob->data, xml_blob->len);
780804
if(doc == NULL) {
@@ -1069,7 +1093,7 @@ ds3_error* ds3_bulk(const ds3_client* client, const ds3_request* _request, ds3_b
10691093
request->length = send_buff.size; // make sure to set the size of the request.
10701094

10711095
xml_blob = g_byte_array_new();
1072-
error_response = _net_process_request(client, request, xml_blob, load_xml_buff, (void*) &send_buff, _ds3_send_xml_buff);
1096+
error_response = _net_process_request(client, request, xml_blob, load_buffer, (void*) &send_buff, _ds3_send_xml_buff);
10731097

10741098
// Cleanup the data sent to the server.
10751099
xmlFreeDoc(doc);

0 commit comments

Comments
 (0)