您的位置:首页 > 其它

libcurl上传文件到服务器的几种方式

2016-04-01 20:25 351 查看

提交表单方式

/***************************************************************************
*                                  _   _ ____  _
*  Project                     ___| | | |  _ \| |
*                             / __| | | | |_) | |
*                            | (__| |_| |  _ <| |___
*                             \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2015, 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.
*
***************************************************************************/
/* <DESC>
* using the multi interface to do a multipart formpost without blocking
* </DESC>
*/

#include <stdio.h>
#include <string.h>
#include <sys/time.h>

#include <curl/curl.h>

int main(void)
{
CURL *curl;

CURLM *multi_handle;
int still_running;

struct curl_httppost *formpost=NULL;
struct curl_httppost *lastptr=NULL;
struct curl_slist *headerlist=NULL;
static const char buf[] = "Expect:";

/* Fill in the file upload field. This makes libcurl load data from
the given file name when curl_easy_perform() is called. */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "sendfile",
CURLFORM_FILE, "postit2.c",
CURLFORM_END);

/* Fill in the filename field */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "filename",
CURLFORM_COPYCONTENTS, "postit2.c",
CURLFORM_END);

/* Fill in the submit field too, even if this is rarely needed */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "submit",
CURLFORM_COPYCONTENTS, "send",
CURLFORM_END);

curl = curl_easy_init();
multi_handle = curl_multi_init();

/* initialize custom header list (stating that Expect: 100-continue is not
wanted */
headerlist = curl_slist_append(headerlist, buf);
if(curl && multi_handle) {

/* what URL that receives this POST */
curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/upload.cgi");
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);

curl_multi_add_handle(multi_handle, curl);

curl_multi_perform(multi_handle, &still_running);

do {
struct timeval timeout;
int rc; /* select() return code */
CURLMcode mc; /* curl_multi_fdset() return code */

fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd = -1;

long curl_timeo = -1;

FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);

/* set a suitable timeout to play around with */
timeout.tv_sec = 1;
timeout.tv_usec = 0;

curl_multi_timeout(multi_handle, &curl_timeo);
if(curl_timeo >= 0) {
timeout.tv_sec = curl_timeo / 1000;
if(timeout.tv_sec > 1)
timeout.tv_sec = 1;
else
timeout.tv_usec = (curl_timeo % 1000) * 1000;
}

/* get file descriptors from the transfers */
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

if(mc != CURLM_OK)
{
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break;
}

/* On success the value of maxfd is guaranteed to be >= -1. We call
select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
to sleep 100ms, which is the minimum suggested value in the
curl_multi_fdset() doc. */

if(maxfd == -1) {
#ifdef _WIN32
Sleep(100);
rc = 0;
#else
/* Portable sleep for platforms other than Windows. */
struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
rc = select(0, NULL, NULL, NULL, &wait);
#endif
}
else {
/* Note that on some platforms 'timeout' may be modified by select().
If you need access to the original value save a copy beforehand. */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
}

switch(rc) {
case -1:
/* select error */
break;
case 0:
default:
/* timeout or readable/writable sockets */
printf("perform!\n");
curl_multi_perform(multi_handle, &still_running);
printf("running: %d!\n", still_running);
break;
}
} while(still_running);

curl_multi_cleanup(multi_handle);

/* always cleanup */
curl_easy_cleanup(curl);

/* then cleanup the formpost chain */
curl_formfree(formpost);

/* free slist */
curl_slist_free_all (headerlist);
}
return 0;
}


put方式

#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;
}


直接post二进制流

int dsdAAASetIcon(struct dsdAAA *dsdAAAObject, char *imagePath,
dsdAAACallBack callback, char *userBuf)
{
char url[512] = { 0 };
char userp[1024];
int res = AAA_SUCCESS;
char *postContent = NULL;
CURL *curl;
struct curl_slist *slist = NULL;
FILE * file;
struct stat fileInfo;

if (imagePath == NULL || (dsdAAAObject == NULL)
|| (callback == NULL) || (userBuf == NULL)) {
dsdl_err("argument can't be empty\n");
return -AAA_ERROR;
}

file = fopen(imagePath, "rb");
if (file == NULL) {
dsdl_err("open file failed\n");
return -AAA_ERROR;
}
stat(imagePath, &fileInfo);// get file size
long fileSize = fileInfo.st_size;
dsdl_debug("文件大小是 = %ld\n", fileSize);
postContent = (char*)malloc(fileSize);
if (postContent == NULL) {
dsdl_err("malloc failed\n");
return -AAA_ERROR;
}
int readCount = fread(postContent, 1, fileSize, file);
if (readCount != fileSize) {
dsdl_err("read file failed\n");
fclose(file);
free(postContent);
return -AAA_ERROR;
}

snprintf(url, sizeof(url), "%s/update_portrait?token=%s",
dsdAAAObject->serverUrl, dsdAAAObject->token);
dsdl_debug("url = %s\n", url);

curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.38.0");
slist = curl_slist_append(slist, "Content-Type: image/png");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, userp);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallback);
dsdl_debug("dsdAAAObject->cookie = %s\n", dsdAAAObject->cookie);
curl_easy_setopt(curl, CURLOPT_COOKIELIST, dsdAAAObject->cookie);// 设置cookie
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_READDATA, file);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, fileSize);//指定图片大小,否则遇到'\0'就停止了
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postContent);

dsdl_debug("start send file to server\n");
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
dsdl_err("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
res = -AAA_ERROR;
goto END;
}
curl_easy_cleanup(curl);

callback(userp, userBuf);
}

END:
fclose(file);
free(postContent);
curl_global_cleanup();
return res;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: