C:通过HTTP请求将文件上传到Google云端硬盘的错误408响应

梁咏琪

我也跟着谷歌教程libcurl的例子,以simple upload通过HTTP的图像谷歌驱动器,但得到的错误404 Not Found,只应在发生resumable upload,根据谷歌指南

Google示例代码:

POST https://www.googleapis.com/upload/drive/v3/files?uploadType=media HTTP/1.1
Content-Type: image/jpeg
Content-Length: [NUMBER_OF_BYTES_IN_FILE]
Authorization: Bearer [YOUR_AUTH_TOKEN]

[JPEG_DATA]

我的代码:

/* for storing the response */
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;
    CURLcode res;

    struct MemoryStruct chunk;

    chunk.memory = malloc(1);
    chunk.size = 0;

    curl_global_init(CURL_GLOBAL_ALL);

    curl_handle = curl_easy_init();
    struct stat file_info;
    FILE *fd;

    /* get a FILE * of the image */
    fd = fopen("grinch.jpg", "rb");
    if(!fd)
        return 1;

    if(fstat(fileno(fd), &file_info) != 0)
        return 1;

    struct curl_slist *chunk = NULL;

    /* Content-Type: image/jpeg */
    chunk = curl_slist_append(chunk5, "Content-Type: image/jpeg");

    /* Content-Length: [NUMBER_OF_BYTES_IN_FILE] */
    char size[200];
    snprintf(size, 200, "Content-Length: %lld", (curl_off_t)file_info.st_size);

    chunk = curl_slist_append(chunk, size);

    /* Authorization: Bearer [YOUR_AUTH_TOKEN] */
    char auth[300];
    strcat(auth, "Authorization: Bearer ");
    strcat(auth, access_token);

    chunk = curl_slist_append(chunk, auth);

    curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, chunk);

    /* POST https://www.googleapis.com/upload/drive/v3/files?uploadType=media */
    curl_easy_setopt(curl_handle, CURLOPT_URL, "https://www.googleapis.com/upload/drive/v3/files");

    curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, "uploadType=media");

    /* [JPEG_DATA] */
    curl_easy_setopt(curl_handle, CURLOPT_POST, 1L);

    curl_easy_setopt(curl_handle, CURLOPT_READDATA, fd);

    curl_easy_setopt(curl_handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);

    /* Save response */
    curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);

    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);

    /* Print response */
    if(res != CURLE_OK) {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", 
    curl_easy_strerror(res));
    }
    else {
        printf("%s\n", chunk.memory);
    }

但是我得到的回应与本教程不符。

谷歌表示应该回应:

HTTP/1.1 200
Content-Type: application/json

{
  "name": "myObject"
}

直接在XCode中运行时得到的响应:

POST /upload/drive/v3/files HTTP/1.1
Host: www.googleapis.com
User-Agent: libcurl-agent/1.0
Accept: */*
Content-Type: image/jpeg
Content-Length: 5123
Authorization: Bearer [my access token]

* upload completely sent off: 16 out of 16 bytes
< HTTP/1.1 408 Request Timeout
< Content-Type: text/html; charset=UTF-8
< Referrer-Policy: no-referrer
< Content-Length: 1557
< Date: Wed, 17 Apr 2019 08:32:18 GMT
< Alt-Svc: quic=":443"; ma=2592000; v="46,44,43,39"
< Connection: close
< 
* Closing connection 0
<!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
  <title>Error 408 (Request Timeout)!!1</title>
  <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
  </style>
  <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
  <p><b>408.</b> <ins>That’s an error.</ins>
  <p>Your client has taken too long to issue its request.  <ins>That’s all we know.</ins>

Program ended with exit code: 0

Error 408 (Request Timeout)!!Google教程中找不到的解释

卡米尔库克

这个:

curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, "uploadType=media");

是相同的:

curl_easy_setopt(curl_handle, CURLOPT_READDATA, "uploadType=media");
curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, a_fucntion_that_reads_that_string);

CURLOPT_POSTFIELDS集合是POST正文。您将发布正文设置为uploadType=media您不想发送该字符串,而是要发送文件。该字符串uploadType=media是url的一部分,您应该将其添加到url中。Google回应404错误-网址/upload/drive/v3/files无效,应为/upload/drive/v3/files?uploadType=media

您应该将网址设置为正确:

curl_easy_setopt(curl_handle, CURLOPT_URL, "https://www.googleapis.com/upload/drive/v3/files?uploadType=media");

除掉

// remove
// curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, "uploadType=media");

而刚刚从读取数据FILE*使用CURLOPT_READDATA

我留下了以下程序(对不起,一团糟):

#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>

const char access_token[] = "Proceeding at three quarters impulse. Make it so, commander!";

int main() {

    CURL * curl_handle = curl_easy_init();
    struct stat file_info;
    FILE *fd;

    stat("grinch.jpg", &file_info);
    printf("%zu\n", file_info.st_size);

    /* get a FILE * of the image */
    fd = fopen("grinch.jpg", "rb");
    if (fd == NULL) {
        abort();
    }

    struct curl_slist *chunk = NULL;

    /* Content-Type: image/jpeg */
    chunk = curl_slist_append(chunk, "Content-Type: image/jpeg");

    /* Content-Length: [NUMBER_OF_BYTES_IN_FILE] */
    char size[200];
    snprintf(size, 200, "Content-Length: %lld", (long long int)file_info.st_size);

    chunk = curl_slist_append(chunk, size);

    /* Authorization: Bearer [YOUR_AUTH_TOKEN] */
    char auth[300];
    strcat(auth, "Authorization: Bearer ");
    strcat(auth, access_token);

    chunk = curl_slist_append(chunk, auth);

    curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, chunk);
    curl_easy_setopt(curl_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_easy_setopt(curl_handle, CURLOPT_URL, "https://www.googleapis.com/upload/drive/v3/files?uploadType=media");
    curl_easy_setopt(curl_handle, CURLOPT_POST, 1L);
    curl_easy_setopt(curl_handle, CURLOPT_READDATA, fd);
    curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
    CURLcode res = curl_easy_perform(curl_handle);

    /* Print response */
    if(res != CURLE_OK) {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
    }
    else {
        printf(" SUCCESS  \n");
    }

    curl_easy_cleanup(curl_handle);
    curl_global_cleanup();

}

对于请求,我得到了响应:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "authError",
    "message": "Invalid Credentials",
    "locationType": "header",
    "location": "Authorization"
   }
  ],
  "code": 401,
  "message": "Invalid Credentials"
 }
}

但这很可能是我的凭据不正确;)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

通过HTTP请求(C)将文件上传到Google云端硬盘

将文件上传到Google云端硬盘?

使用http上传到Google云端硬盘文件夹

使用gapi将文件上传到Google云端硬盘

使用php curl将文件上传到Google云端硬盘

在后台将文件上传到Google云端硬盘

使用Dropzone将文件上传到Google云端硬盘

将文件从网络上传到Google云端硬盘

将文件从Blobstore上传到Google云端硬盘

使用意图将文件上传到Google云端硬盘

通过Javascript API将多个文件上传到Google云端硬盘的最佳策略

Google云端硬盘API将文件上传到Java团队硬盘

无法将文件上传到Google云端硬盘中的文件夹

无法将文件上传到Google云端硬盘上的特定文件夹

将文件上传到Google云端硬盘中的特定文件夹

使用Windows服务自动将文件上传到Google云端硬盘文件流

Python:如何使用folderId将文件上传到Google云端硬盘中的特定文件夹

飞镖:http发布上传到Google云端硬盘

Angular Gapi将简单文本上传到Google云端硬盘

使用PyDrive将图片上传到Google云端硬盘

将文件上传到Google云端硬盘后,如何处理该事件(调用脚本)?

使用Curl将文件上传到Google云端硬盘会显示401

使用Android将文本文件上传到Google云端硬盘

将内存中的文件下载并上传到Google云端硬盘

使用cURL将文件上传到Google云端硬盘-access_token过期问题

可靠地将大文件上传到Google云端硬盘

使用javascript(无html表单)以编程方式将文件上传到Google云端硬盘

如何将持续更新的文件夹上传到Google云端硬盘?

pydrive:尝试将文件从远程服务器上传到Google云端硬盘