我正在编写程序以通过HTTP访问Google Drive REST API。
我正在关注you're not mutating和Google Tutorial
步骤:请求设备和用户密码
curl -d "client_id=client_id&scope=https://www.googleapis.com/auth/drive.file" \
https://accounts.google.com/o/oauth2/device/code
步骤:轮询Google的授权服务器
curl -d "client_id=<client_id>&client_secret=<client_secret>& \
code=<device_code>&grant_type=http://oauth.net/grant_type/device/1.0" \
-H "Content-Type: application/x-www-form-urlencoded" \
https://www.googleapis.com/oauth2/v4/token
我运行了几次代码,有时效果很好,但是大多数时候失败了,这让我感到沮丧。
我的代码
struct MemoryStruct {
char *memory;
size_t size;
};
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
char *ptr = realloc(mem->memory, mem->size + realsize + 1);
if(ptr == NULL) {
/* out of memory! */
printf("not enough memory (realloc returned NULL)\n");
return 0;
}
mem->memory = ptr;
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
int main(void)
{
CURL *curl_handle, *curl_handle2;
CURLcode res, res2;
struct MemoryStruct chunk, chunk2;
chunk.memory = malloc(1);
chunk.size = 0;
curl_global_init(CURL_GLOBAL_ALL);
请求设备和用户代码
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, "https://accounts.google.com/o/oauth2/device/code");
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, "client_id=<my_client_id>.apps.googleusercontent.com&scope=https://www.googleapis.com/auth/drive.file");
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
res = curl_easy_perform(curl_handle);
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
else {
//skip some codes of extracting the user_code here
}
curl_easy_cleanup(curl_handle);
free(chunk.memory);
轮询Google的授权服务器
printf("Enter below code on 'https://www.google.com/device' :\n");
printf("%s\n", user_code);
printf("Press enter when finish\n");
while( getchar() != '\n' );
curl_handle2 = curl_easy_init();
curl_easy_setopt(curl_handle2, CURLOPT_URL, "https://www.googleapis.com/oauth2/v4/token");
char url[300];
strcat(url, "client_id=<my_client_id>.apps.googleusercontent.com&client_secret=<my_client_secret>&code=");
strcat(url, device_code);
strcat(url, "&grant_type=http://oauth.net/grant_type/device/1.0");
curl_easy_setopt(curl_handle2, CURLOPT_POSTFIELDS, url);
curl_easy_setopt(curl_handle2, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl_handle2, CURLOPT_WRITEDATA, (void *)&chunk2);
curl_easy_setopt(curl_handle2, CURLOPT_USERAGENT, "libcurl-agent/1.0");
res2 = curl_easy_perform(curl_handle2);
if(res2 != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res2));
}
else {
//do something here
}
curl_easy_cleanup(curl_handle2);
free(chunk2.memory);
此行res = curl_easy_perform(curl_handle);
上出现错误
malloc: *** error for object 0x10068a400: pointer being realloc'd was not allocated
test(3989,0x1000ab5c0) malloc: *** set a breakpoint in malloc_error_break to debug
我在运行方案中启用了Address Sanitizer
,它显示:
ERROR: AddressSanitizer: attempting double-free on 0x6110000205c0 in thread T0:
2019-04-18 10:17:28.969346+0800 atos[3802:117177] examining /Users/USER/Library/Developer/Xcode/DerivedData/test-dbydzdrhbxzzjcgcmnrcjvlrthal/Build/Products/Debug/test [3789]
#0 0x1001333d7 in wrap_realloc (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x5c3d7)
#1 0x1000030f9 in WriteMemoryCallback main.c:30
#2 0x7fff796da5e4 in Curl_client_chop_write (libcurl.4.dylib:x86_64+0xb5e4)
#3 0x7fff796f652a in Curl_httpchunk_read (libcurl.4.dylib:x86_64+0x2752a)
#4 0x7fff796f134b in Curl_readwrite (libcurl.4.dylib:x86_64+0x2234b)
#5 0x7fff796fa6b9 in multi_runsingle (libcurl.4.dylib:x86_64+0x2b6b9)
#6 0x7fff796f9b83 in curl_multi_perform (libcurl.4.dylib:x86_64+0x2ab83)
#7 0x7fff796f2db6 in curl_easy_perform (libcurl.4.dylib:x86_64+0x23db6)
#8 0x100002363 in main main.c:120
#9 0x7fff7bcb63d4 in start (libdyld.dylib:x86_64+0x163d4)
0x6110000205c0 is located 0 bytes inside of 246-byte region [0x6110000205c0,0x6110000206b6)
freed by thread T0 here:
#0 0x10013320d in wrap_free (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x5c20d)
#1 0x1000021cd in main main.c:98
#2 0x7fff7bcb63d4 in start (libdyld.dylib:x86_64+0x163d4)