Skip to content

Commit

Permalink
More #19 work
Browse files Browse the repository at this point in the history
Refactor the uri building to use str_ts.
Use curl_interface for the auth request.
  • Loading branch information
James Cline committed May 28, 2012
1 parent e8a46e7 commit 2d321bf
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 117 deletions.
188 changes: 72 additions & 116 deletions gd_interface.c
Expand Up @@ -138,18 +138,17 @@ char* load_file(const char* path, const char* name)
/** Callback for libcurl for parsing json auth tokens.
*
*/
size_t curl_post_callback(void *data, size_t size, size_t nmemb, void *store)
int curl_post_callback(struct gdi_state *state, struct request_t *request)
{
struct gdi_state *state = (struct gdi_state*) store;
struct json_object *json = json_tokener_parse(data);
struct json_object *json = json_tokener_parse(request->response.body.str);
union func_u func;

struct json_object *tmp = json_object_object_get(json, "error");
if(tmp != NULL)
{
fprintf(stderr, "Error: %s\n", json_object_get_string(tmp));
state->callback_error = 1;
return size*nmemb;
return 1;
}

tmp = json_object_object_get(json, "access_token");
Expand Down Expand Up @@ -183,10 +182,7 @@ size_t curl_post_callback(void *data, size_t size, size_t nmemb, void *store)
tmp = json_object_object_get(json, "expires_in");
state->token_expiration = json_object_get_int(tmp);

// libcurl expects this to "read" as much data as it received from the server
// since json-c is doing all the work here, unless it errors we may as well
// return the size libcurl gave us for the data
return size*nmemb;
return 0;
}

void print_api_info(const char* path)
Expand Down Expand Up @@ -349,52 +345,6 @@ int gdi_init(struct gdi_state* state)
fstack_push(estack, state->curlmulti, &func, 3);

/* Authenticate the application */

// Calculating the correct value is more trouble than it is worth
/*
char *complete_authuri = (char *) malloc(sizeof(char) * 3000);
if(complete_authuri == NULL)
goto init_fail;
func.func1 = free;
fstack_push(gstack, complete_authuri, &func, 1);
char *iter = complete_authuri;
// Create the authentication request URI
// There might be a cleaner way to do this...
iter += add_unencoded_str(iter, auth_uri, sizeof(auth_uri));
iter += add_unencoded_str(iter, response_type_code, sizeof(response_type_code));
iter += add_unencoded_str(iter, scope, sizeof(scope));
iter += add_encoded_uri(iter, email_scope, sizeof(email_scope));
*iter = '+';
++iter;
iter += add_encoded_uri(iter, profile_scope, sizeof(profile_scope));
*iter = '+';
++iter;
iter += add_encoded_uri(iter, docs_scope, sizeof(docs_scope));
*iter = '+';
++iter;
iter += add_encoded_uri(iter, docsguc_scope, sizeof(docsguc_scope));
*iter = '+';
++iter;
iter += add_encoded_uri(iter, spreadsheets_scope, sizeof(spreadsheets_scope));
*iter = '+';
++iter;
iter += add_unencoded_str(iter, redirect, sizeof(redirect));
iter += add_encoded_uri(iter, state->redirecturi, strlen(state->redirecturi)+1);
iter += add_unencoded_str(iter, clientid, sizeof(clientid));
iter += add_unencoded_str(iter, state->clientid, strlen(state->clientid)+1);
*/

struct str_t complete_authuri;
func.func1 = str_destroy;
fstack_push(gstack, &complete_authuri, &func, 1);
Expand All @@ -408,7 +358,7 @@ int gdi_init(struct gdi_state* state)
struct str_t redirect_param;
struct str_t scope_param;
struct str_t client_id_param;
//struct str_t client_secret_param;
struct str_t client_secret_param;
struct str_t grant_type_param;

struct str_t *email_scope_str = str_urlencode_char(email_scope, 0);
Expand All @@ -419,6 +369,7 @@ int gdi_init(struct gdi_state* state)

struct str_t *redirecturi_str = str_urlencode_char(state->redirecturi, 0);
struct str_t *clientid_str = str_urlencode_char(state->clientid, 0);
struct str_t *clientsecret_str = str_urlencode_char(state->clientsecrets, 0);


str_init_create(&plus, "+", 0);
Expand All @@ -430,33 +381,35 @@ int gdi_init(struct gdi_state* state)
str_init_create(&redirect_param, "redirect_uri=", 0);
str_init_create(&scope_param, "scope=", 0);
str_init_create(&client_id_param, "client_id=", 0);
//str_init_create(&client_secret_param, "client_secret", 0);
str_init_create(&client_secret_param, "client_secret=", 0);
str_init_create(&grant_type_param, "grant_type=authorization_code", 0);

const struct str_t const* uri_parts[] =
{
&que,
&response_type_code,
&amp,
&scope_param,
email_scope_str,
&plus,
profile_scope_str,
&plus,
docs_scope_str,
&plus,
docsguc_scope_str,
&plus,
spreadsheets_scope_str,
&amp,
&redirect_param,
redirecturi_str,
&amp,
&client_id_param,
clientid_str
};
str_init_create(&complete_authuri, auth_uri, sizeof(auth_uri));
str_concat(&complete_authuri, sizeof(uri_parts)/sizeof(const struct str_t const*), uri_parts);
{ // So we can reuse variable name again
const struct str_t const* uri_parts[] =
{
&que,
&response_type_code,
&amp,
&scope_param,
email_scope_str,
&plus,
profile_scope_str,
&plus,
docs_scope_str,
&plus,
docsguc_scope_str,
&plus,
spreadsheets_scope_str,
&amp,
&redirect_param,
redirecturi_str,
&amp,
&client_id_param,
clientid_str
};
str_init_create(&complete_authuri, auth_uri, 0);
str_concat(&complete_authuri, sizeof(uri_parts)/sizeof(const struct str_t const*), uri_parts);
}

printf("Please open this in a web browser and authorize fuse-google-drive:\n%s\n", complete_authuri.str);

Expand Down Expand Up @@ -501,39 +454,42 @@ int gdi_init(struct gdi_state* state)
}

// Prepare and make the request to exchange the code for an access token
CURL *auth_handle = curl_easy_init();
if(auth_handle == NULL)
goto init_fail;
func.func1 = curl_easy_cleanup;
fstack_push(gstack, auth_handle, &func, 1);

// Using complete_authuri to store POST data rather than allocating more space
/*
iter = complete_authuri;
iter += add_unencoded_str(iter, codeparameter, sizeof(codeparameter));
iter += add_encoded_uri(iter, state->code, strlen(state->code)+1);
iter += add_unencoded_str(iter, clientid, sizeof(clientid));
iter += add_encoded_uri(iter, state->clientid, strlen(state->clientid)+1);
iter += add_unencoded_str(iter, clientsecret, sizeof(clientsecret));
iter += add_encoded_uri(iter, state->clientsecrets, strlen(state->clientsecrets)+1);
iter += add_unencoded_str(iter, redirect, sizeof(redirect));
iter += add_encoded_uri(iter, state->redirecturi, strlen(state->redirecturi)+1);
iter += add_unencoded_str(iter, granttype, sizeof(granttype));
// TODO: errors
//curl_easy_setopt(auth_handle, CURLOPT_VERBOSE, 1);
curl_easy_setopt(auth_handle, CURLOPT_USE_SSL, CURLUSESSL_ALL); // SSL
curl_easy_setopt(auth_handle, CURLOPT_URL, token_uri); // set URI
curl_easy_setopt(auth_handle, CURLOPT_POSTFIELDS, complete_authuri); // BODY
// set curl_post_callback for parsing the server response
curl_easy_setopt(auth_handle, CURLOPT_WRITEFUNCTION, curl_post_callback);
// set curl_post_callback's last parameter to state
curl_easy_setopt(auth_handle, CURLOPT_WRITEDATA, state);
curl_easy_perform(auth_handle); // POST
if(state->callback_error)
goto init_fail;
str_clear(&complete_authuri);

struct str_t *code_str = str_urlencode_char(code, 0);
{
const struct str_t const* uri_parts[] =
{
&code_param,
code_str,
&amp,
&client_id_param,
clientid_str,
&amp,
&client_secret_param,
clientsecret_str,
&amp,
&redirect_param,
redirecturi_str,
&amp,
&grant_type_param
};
str_init(&complete_authuri);
if(str_concat(&complete_authuri, sizeof(uri_parts)/sizeof(const struct str_t const*), uri_parts))
goto init_fail;
printf("%s\n", complete_authuri.str);

struct str_t token_uri_str;
str_init_create(&token_uri_str, token_uri, 0);

struct request_t request;
ci_init(&request, &token_uri_str, 0, NULL, complete_authuri.str, POST);
ci_request(&request);
if(curl_post_callback(state, &request))
goto init_fail;
ci_destroy(&request);
}

*/
create_oauth_header(state);
gdi_get_file_list(state);
if(create_hash_table(state->num_files*4, state->head))
Expand Down Expand Up @@ -691,7 +647,7 @@ void gdi_get_file_list(struct gdi_state *state)
struct str_t* next = NULL;

struct request_t request;
ci_init(&request, &uri, 1, &state->oauth_header, GET);
ci_init(&request, &uri, 1, &state->oauth_header, NULL, GET);
do
{

Expand Down Expand Up @@ -724,7 +680,7 @@ int gdi_check_update(struct gdi_state* state, struct gd_fs_entry_t* entry)
if(entry->md5set)
{
struct request_t request;
ci_init(&request, &entry->feed, 1, &state->oauth_header, GET);
ci_init(&request, &entry->feed, 1, &state->oauth_header, NULL, GET);
ci_request(&request);

struct str_t* md5 = xml_get_md5sum(&request.response.body);
Expand Down Expand Up @@ -755,7 +711,7 @@ int gdi_load(struct gdi_state* state, struct gd_fs_entry_t* entry)
ret = 0;
break;
case 1:
ci_init(&request, &entry->src, 1, &state->oauth_header, GET);
ci_init(&request, &entry->src, 1, &state->oauth_header, NULL, GET);
ci_request(&request);

str_swap(&request.response.body, &entry->cache);
Expand All @@ -767,7 +723,7 @@ int gdi_load(struct gdi_state* state, struct gd_fs_entry_t* entry)
else
{
struct request_t request;
ci_init(&request, &entry->src, 1, &state->oauth_header, GET);
ci_init(&request, &entry->src, 1, &state->oauth_header, NULL, GET);
ci_request(&request);

str_swap(&request.response.body, &entry->cache);
Expand Down
11 changes: 10 additions & 1 deletion str.c
Expand Up @@ -38,6 +38,15 @@ int str_init_create(struct str_t* str, const char const* value, size_t size)
return str_char_concat(str, value, size);
}

int str_clear(struct str_t* str)
{
if(!str)
return 0;
memset(str->str, 0, str->reserved);
str->len = 0;
return 0;
}

int str_destroy(struct str_t* str)
{
if(!str)
Expand All @@ -61,7 +70,7 @@ int str_concat(struct str_t* str, size_t str_count, const struct str_t const* st
// Copy strings[] values into str
for(count = 0; count < str_count; ++count)
{
memcpy(str->str + ((str->len) ? str->len - 1 : 0), strings[count]->str, strings[count]->len);
memcpy(str->str + str->len, strings[count]->str, strings[count]->len);
str->len += strings[count]->len;
}
// Terminate with null
Expand Down
1 change: 1 addition & 0 deletions str.h
Expand Up @@ -30,6 +30,7 @@ struct str_t {
void str_init(struct str_t* str);
int str_init_create(struct str_t* str, const char const* value, size_t size);
int str_destroy(struct str_t* str);
int str_clear(struct str_t* str);

int str_resize(struct str_t *str, size_t new_size);

Expand Down

0 comments on commit 2d321bf

Please sign in to comment.