gpt4 book ai didi

c - 使用 C 的原始 libcurl JSON PUT 请求

转载 作者:行者123 更新时间:2023-12-02 00:39:15 26 4
gpt4 key购买 nike

我目前正在编写一个类似 REST 的客户端,只需要执行 PUT 请求。

问题:
运行该程序并没有在 URL 的 API 上给出正确的结果,我不知道为什么。

使用curl_easy_perform(curl)在调用时不会抛出错误。但 URL 的 API 上并未生成预期结果。

使用curl_easy_send(curl,..,..,..)抛出一个:不支持的协议(protocol)错误

假设:
我假设我使用curl_easy_opts的顺序有问题?我什至错过了几行关键行?

我一直在这里阅读其他人如何执行 PUT 请求并一直在使用他们的方法。

计划摘要:

我的程序提示用户输入一些字符串/字符数据,然后我自己构建字符串,例如 header 和有效负载。 header 和有效负载均为 JSON 格式,但有效负载只是一个字符串(在本例中为 char *str = (char *)mallo.. 等)。 header 的构造方式如下所示。

我的 header 正在使用

构建
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
//there is more content being appended to the header

CURL 函数调用:

    //init winsock stuff
curl_global_init(CURL_GLOBAL_ALL);

//get a curl handle
curl = curl_easy_init();

if(curl){
//append the headers
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

//specify the target URL
curl_easy_setopt(curl, CURLOPT_URL, url);

//connect ( //i added this here since curl_easy_send() says it requires it. )
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY,1L);

//specify the request (PUT in our case)
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");

//append the payload
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);

res = curl_easy_perform(curl);
//res = curl_easy_send(curl, payload, strlen(payload),&iolen);

//check for errors
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));

curl_easy_cleanup(curl);
}

最佳答案

您不应使用 CURLOPT_CONNECT_ONLY 选项或 curl_easy_send() 函数,这些函数旨在用于自定义的非 HTTP 协议(protocol)。

参见this page有关如何使用 libcurl 执行 PUT 请求的示例。基本上,您希望启用 CURLOPT_UPLOADCURLOPT_PUT 选项来表示您正在执行 PUT 请求并启用随请求上传正文,然后设置CURLOPT_READDATACURLOPT_INFILESIZE_LARGE 选项告诉 libcurl 如何读取您正在上传的数据以及数据有多大。

就您而言,如果内存中已有数据,则无需从文件中读取数据,只需在读取回调中使用 memcpy() 即可。

复制的示例代码如下:

/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <curl/curl.h>

/*
* This example shows a HTTP PUT operation. PUTs a file given as a command
* line argument to the URL also given on the command line.
*
* This example also uses its own read callback.
*
* Here's an article on how to setup a PUT handler for Apache:
* http://www.apacheweek.com/features/put
*/

static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
size_t retcode;
curl_off_t nread;

/* in real-world cases, this would probably get this data differently
as this fread() stuff is exactly what the library already would do
by default internally */
retcode = fread(ptr, size, nmemb, stream);

nread = (curl_off_t)retcode;

fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T
" bytes from file\n", nread);

return retcode;
}

int main(int argc, char **argv)
{
CURL *curl;
CURLcode res;
FILE * hd_src ;
struct stat file_info;

char *file;
char *url;

if(argc < 3)
return 1;

file= argv[1];
url = argv[2];

/* get the file size of the local file */
stat(file, &file_info);

/* get a FILE * of the same file, could also be made with
fdopen() from the previous descriptor, but hey this is just
an example! */
hd_src = fopen(file, "rb");

/* In windows, this will init the winsock stuff */
curl_global_init(CURL_GLOBAL_ALL);

/* get a curl handle */
curl = curl_easy_init();
if(curl) {
/* we want to use our own read function */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);

/* enable uploading */
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);

/* HTTP PUT please */
curl_easy_setopt(curl, CURLOPT_PUT, 1L);

/* specify target URL, and note that this URL should include a file
name, not only a directory */
curl_easy_setopt(curl, CURLOPT_URL, url);

/* now specify which file to upload */
curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);

/* provide the size of the upload, we specicially typecast the value
to curl_off_t since we must be sure to use the correct data size */
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
(curl_off_t)file_info.st_size);

/* Now run off and do what you've been told! */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));

/* always cleanup */
curl_easy_cleanup(curl);
}
fclose(hd_src); /* close the local file */

curl_global_cleanup();
return 0;
}

关于c - 使用 C 的原始 libcurl JSON PUT 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23203885/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com