前言
通过使用libcur可以快捷地对图片进行上传和下载,下载和ftp流程类似,上传需要注意图片格式和服务器表单等配置要求
上传
根据libcur官方描述:
curl_mime_init creates a handle to a new empty mime structure intended to be used with easy_handle. This mime structure can be subsequently filled using the mime API, then attached to easy_handle using option CURLOPT_MIMEPOST within a curl_easy_setopt call.
Using a mime handle is the recommended way to post an HTTP form, format and send a multi-part email with SMTP or upload such an email to an IMAP server.
http头参考如下:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryHGUYvaM49N5Bm27p
mine内容参考如下:
Content-Disposition: form-data; name=“files”; filename=“test.jpg”
Content-Type: image/jpeg
参考libcurl示例代码,结合以上要求,实际上不同服务器参数可能有差异,需要根据自身配置来调整
int file_upload(const char* url, const char* filename)
{
int ret = -1;
CURL* easy_handle;
CURLcode res;
CURLcode code;
code = curl_global_init(CURL_GLOBAL_ALL);
if (CURLE_OK != code) {
fprintf(stderr, "init libcurl failed\n");
return ret;
}
curl_mime *mime;
curl_mimepart *part;
easy_handle = curl_easy_init();
/* Build an HTTP form with a single field named "data", */
mime = curl_mime_init(easy_handle);
part = curl_mime_addpart(mime);
curl_mime_name(part, "files");
curl_mime_filedata(part, filename);
curl_mime_type(part, "image/jpeg");
curl_easy_setopt(easy_handle, CURLOPT_URL, url);
curl_easy_setopt(easy_handle, CURLOPT_MIMEPOST, mime);
curl_easy_setopt(easy_handle, CURLOPT_VERBOSE, 1);
res = curl_easy_perform(easy_handle);
/* Now run off and do what you've been told! */
if (res != CURLE_OK) {
/* we failed */
printf("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
} else {
long httpStatus;
curl_easy_getinfo(easy_handle, CURLINFO_RESPONSE_CODE, &httpStatus);
printf("httpStatus = %ld\n", httpStatus);
ret = 0;
}
curl_easy_cleanup(easy_handle);
curl_mime_free(mime);
curl_global_cleanup();
return ret;
}
下载
参考libcur中的ftpget,只需要一个简单的GET方法,把接收到的数据保存成图片文件即可
struct FtpFile {
const char *filename;
FILE *stream;
};
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
struct FtpFile *out = (struct FtpFile *)stream;
if (!out->stream) {
/* open file for writing */
out->stream = fopen(out->filename, "wb");
if (!out->stream) {
return -1; /* failure, can't open file to write */
}
}
return fwrite(buffer, size, nmemb, out->stream);
}
int file_download(const char* url, const char* filename)
{
int ret = -1;
CURL *curl;
CURLcode res;
struct FtpFile ftpfile = {
filename, /* name to store the file as if successful */
NULL
};
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
/*
* You better replace the URL with one that works!
*/
// url: "ftp://ftp.example.com/curl/curl-7.9.2.tar.gz"
curl_easy_setopt(curl, CURLOPT_URL, url);
/* Define our callback to get called when there's data to be written */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
/* Set a pointer to our struct to pass to the callback */
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 100L);
/* Switch on full protocol/debug output */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
/* we failed */
printf("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
} else {
unsigned int httpStatus;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpStatus);
printf("httpStatus = %u\n", httpStatus);
if (httpStatus == 200) {
ret = 0;
}
}
/* always cleanup */
curl_easy_cleanup(curl);
}
if (ftpfile.stream) {
fclose(ftpfile.stream); /* close the local file */
}
curl_global_cleanup();
return ret;
}