+static s3_result_t
+oauth2_get_access_token(
+ S3Handle *hdl)
+{
+ GString *query;
+ CurlBuffer data;
+ s3_result_t result = S3_RESULT_FAIL;
+ static result_handling_t result_handling[] = {
+ { 200, 0, 0, S3_RESULT_OK },
+ { 204, 0, 0, S3_RESULT_OK },
+ RESULT_HANDLING_ALWAYS_RETRY,
+ { 0, 0, 0, /* default: */ S3_RESULT_FAIL }
+ };
+ char *body;
+ regmatch_t pmatch[2];
+
+ g_assert(hdl != NULL);
+
+ query = g_string_new(NULL);
+ g_string_append(query, "client_id=");
+ g_string_append(query, hdl->client_id);
+ g_string_append(query, "&client_secret=");
+ g_string_append(query, hdl->client_secret);
+ g_string_append(query, "&refresh_token=");
+ g_string_append(query, hdl->refresh_token);
+ g_string_append(query, "&grant_type=refresh_token");
+
+ data.buffer_len = query->len;
+ data.buffer = query->str;
+ data.buffer_pos = 0;
+ data.max_buffer_size = data.buffer_len;
+
+ hdl->x_storage_url = "https://accounts.google.com/o/oauth2/token";
+ hdl->getting_oauth2_access_token = 1;
+ result = perform_request(hdl, "POST", NULL, NULL, NULL, NULL,
+ "application/x-www-form-urlencoded", NULL,
+ s3_buffer_read_func, s3_buffer_reset_func,
+ s3_buffer_size_func, s3_buffer_md5_func,
+ &data, NULL, NULL, NULL, NULL, NULL,
+ result_handling);
+ hdl->x_storage_url = NULL;
+ hdl->getting_oauth2_access_token = 0;
+
+ /* use strndup to get a null-terminated string */
+ body = g_strndup(hdl->last_response_body, hdl->last_response_body_size);
+ if (!body) {
+ hdl->last_message = g_strdup(_("No body received for location request"));
+ goto cleanup;
+ } else if ('\0' == body[0]) {
+ hdl->last_message = g_strdup(_("Empty body received for location request"));
+ goto cleanup;
+ }
+
+ if (!s3_regexec_wrap(&access_token_regex, body, 2, pmatch, 0)) {
+ hdl->access_token = find_regex_substring(body, pmatch[1]);
+ hdl->x_auth_token = g_strdup(hdl->access_token);
+ }
+ if (!s3_regexec_wrap(&expires_in_regex, body, 2, pmatch, 0)) {
+ char *expires_in = find_regex_substring(body, pmatch[1]);
+ hdl->expires = time(NULL) + atoi(expires_in) - 600;
+ g_free(expires_in);
+ }
+
+cleanup:
+ g_free(body);
+ return result == S3_RESULT_OK;
+}
+