使用C的原始libcurl JSON PUT请求 [英] a raw libcurl JSON PUT request using C
问题描述
我目前正在编写一个类似REST的客户端,只需要执行PUT请求即可。
I am currently writing a REST-like client that only is required to do PUT requests.
问题:
运行程序无法在URL的API上给我正确的结果,我也不知道为什么。
Problem:
Running the program is not giving me the correct results on the URL's API and I do not know why.
使用curl_easy_perform(curl)不会在调用时引发错误。但是,预期的结果不是在URL的API上生成的。
Using curl_easy_perform(curl) does not throw an error when called. But the expected result is not generated on the URL's API.
使用curl_easy_send(curl,..,.....)会抛出:不支持的协议错误
Using curl_easy_send(curl,..,..,..) throws a : unsupported protocol error
假设:
我假设我使用curl_easy_opts的顺序有问题吗?我什至缺少几个关键点?
Assumption:
I am assuming the order in which I am using the curl_easy_opts is a problem? And I am even missing a couple of key lines?
我一直在这里阅读其他人如何进行PUT请求并一直使用他们的方法。
I have been reading on here of how other people do PUT requests and have been using their methods.
程序摘要:
我的程序提示用户输入一些字符串/字符数据,然后,我自己构造诸如标头和有效负载。标头和有效负载均为JSON格式,但有效负载只是一个字符串(在这种情况下,为char * str =(char *)mallo ..等)。标头的构造如下所示。
My program prompts the user for some string/character data, and from that, I construct the strings myself such as the header and the payload. The header and payload are both in JSON format but the payload is simply a string ( in this case, a char *str = (char *)mallo.. etc). How the header is constructed is shown below.
我的标头使用
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协议。
You should not be using the CURLOPT_CONNECT_ONLY
option or curl_easy_send()
function, those are intended to be used for custom, non-HTTP protocols.
请参见此页面一个使用libcurl进行PUT请求的示例。基本上,您想启用 CURLOPT_UPLOAD
和 CURLOPT_PUT
选项,以表示您正在执行PUT请求并启用上传带有请求的正文,然后设置 CURLOPT_READDATA
和 CURLOPT_INFILESIZE_LARGE
选项以告诉libcurl如何读取数据
See this page for an example of how to do a PUT request with libcurl. Basically, you want to enable the CURLOPT_UPLOAD
and CURLOPT_PUT
options to say that you're doing a PUT request and to enable uploading a body with the request, and then you set the CURLOPT_READDATA
and CURLOPT_INFILESIZE_LARGE
options to tell libcurl how to read the data you're uploading and how big the data is.
在您的情况下,如果您已经在内存中存储了数据,则无需从中读取数据一个文件,就可以在读取回调中将它 memcpy()
包起来。
In your case, if you already have the data in memory, then you don't need to read it out of a file, and you can just memcpy()
it inside your read callback.
下面复制的示例代码:
/***************************************************************************
* _ _ ____ _
* 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的原始libcurl JSON PUT请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!