zoukankan      html  css  js  c++  java
  • libCurl的文件上传

    最近在需要使用curl的上传功能,使用libCurl来实现。因此,先使用curl命令操作,然后再使用libCurl实现。

    基于Http协议的文件上传的标准方法是: 基于POST Form的文件上传  RFC1867。

    这个方法使用非常广泛,这个RFC规定了FORM上传文件的标准方法,如下介绍了基于libcurl来开发upload功能。

    开发实现过程 

                         1. 使用curl 命令行执行代码,  2. 跟踪分析 curl的request和response, 3.使用libCurl的API进行开发实现

    0. 搭建  upload server

       --- 这个请google一些WebServer的搭建,已经参考RFC1867 或网上例子选择任意一种语言,编写网络后太处理代码。

        我使用python的django framework编写了一个upload处理页面,

       需要FORM的字段 

        Title-newFileNameInServer

        FILE=@....../abc/

        url http://192.168.0.61/due/upload/

    1. 使用Curl 上传文件的命令

                      curl -F"title=dddd.txt" -F "file=@/home/chenglun/upload/abc" http://192.168.0.61/due/upload/

    2. 分析

                    curl --trace trace.log -F"title=dddd.txt" -F "file=@/home/chenglun/upload/abc" http://192.168.0.61/due/upload/

    log:

    => connect....

    => Send header, 298 bytes (0x12a)

    POST /due/upload  ......  bound.....

    <= Recv header, 23 bytes (0x17)

    HTTP/1.1 100 Continue..

    => Send data, 249 bytes (0xf9)

    bound...

    Content-Disposition:form-data; name ....

    ....

    bound...

    <= Recv header, 17 bytes (0x11)

    HTTP/1.1 200 OK..

    ..............

    从trace中可以知道,只需要building一个form,加入对应的Key=value部分然后使用curl的request即可实现如上传输过程。

    3. 使用libCurl实现

    使用API有:   curl_formadd(); curl_formfree 生成 一个from,然后使用 curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);设置curl,然后执行,即可。

    curl_formadd()使用参考, libCurl的文档,文档有例子的。

    代码上半部:

    int main() {
        CURL *curl;
        CURLcode res;
        struct data config;
        struct stat file_info; 

        const char * localfile = "/home/chenglun/upload/abc"";
        FILE * fp = fopen(localfile, "rb"); 
        if(!fp)    {
            return -1;
        }

        if(fstat(fileno(fp), &file_info) != 0)    {
            return -1;
        }

        curl = curl_easy_init();

        if(curl) {
            struct curl_httppost* post = NULL;
            struct curl_httppost* last = NULL;

            const char * remoteNewFileKey = "title";
            const char * remoteNewFileName = "d.ttt";
            curl_formadd(&post, &last, CURLFORM_COPYNAME, remoteNewFileKey, CURLFORM_COPYCONTENTS, remoteNewFileName, CURLFORM_END);  
            curl_formadd(&post, &last, CURLFORM_COPYNAME, "file", CURLFORM_FILE, localfile, CURLFORM_END);
            curl_formadd(&post, &last, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "send", CURLFORM_END);
            curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);

    下半部:

                    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size); // upload file size--- Content-Length: size

            curl_easy_setopt(curl, CURLOPT_MAX_SEND_SPEED_LARGE, 20*1000);    // speed limit

            // verbal -- for debug                
            // curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);                
            // curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);                    
                    // curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &config);                        
                    
                    // progress callback                
            //curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);                
            //curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, cbProgress);
            res = curl_easy_perform(curl);
            if(res != 0){
                ERROR("err string %s", curl_easy_strerror(res));                
            }
            curl_easy_cleanup(curl);   
        } 
        fclose(fp);
        return 0;
    }

  • 相关阅读:
    iOS项目之wifi局域网传输文件到iPhone的简单实现
    iOS项目之苹果审核被拒
    iOS项目之模拟请求数据
    nvm-window常用命令
    初探浏览器渲染原理
    node + mongodb 简单实现自己的查询接口
    快速理解_.debounce方法
    tr标签使用hover的box-shadow效果不生效
    一个简单的Node命令行程序:文件浏览
    打造丝般顺滑的 H5 翻页库(传送门)
  • 原文地址:https://www.cnblogs.com/lidabo/p/4159598.html
Copyright © 2011-2022 走看看