c++ 使用curl上传文件/multiform

2,740 阅读1分钟

post multiform

static size_t WriteCallback(char *contents, size_t size, size_t nmemb, void *userp)
    {
        ((std::string *)userp)->append((char *)contents, size * nmemb);
        return size * nmemb;
    }

    bool upload(string old_filename)
    {
        bool ok = false;
        std::string contents;
        std::ifstream in(old_filename, std::ios::in | std::ios::binary);

        if (in)
        {
            in.seekg(0, std::ios::end);
            contents.resize(in.tellg());
            in.seekg(0, std::ios::beg);
            in.read(&contents[0], contents.size());
            in.close();
        }
        //##

        CURL *curl;
        CURLcode res;

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

        curl_global_init(CURL_GLOBAL_ALL);
        std::cout << "pkgID: " << std::to_string(packageId).c_str() << std::endl;
        // set up the header
        curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME,
                     "cache-control:", CURLFORM_COPYCONTENTS, "no-cache",
                     CURLFORM_END);

        curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME,
                     "content-type:", CURLFORM_COPYCONTENTS,
                     "multipart/form-data", CURLFORM_END);

        curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME,
                     "file", // <--- the (in this case) wanted file-Tag!
                     CURLFORM_BUFFER, "data", CURLFORM_BUFFERPTR,
                     contents.data(), CURLFORM_BUFFERLENGTH, contents.size(),
                     CURLFORM_END);
        int id = packageId;
        char str[10];
        sprintf(str, "%d", id);
        std::cout << "ID: " << id << std::endl;
        curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME,
                     "packageId", // <--- the (in this case) wanted file-Tag!
                     CURLFORM_PTRCONTENTS, str,
                     CURLFORM_END);
        curl = curl_easy_init();

        headerlist = curl_slist_append(headerlist, buf);
        std::string readBuffer;
        if (curl)
        {
            curl_easy_setopt(
                curl, CURLOPT_URL,
                "***url***");

            curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
            curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

            res = curl_easy_perform(curl);
            /* Check for errors */
            nlohmann::json json = nlohmann::json::parse(readBuffer);
            std::cout << json << std::endl;
            if (res != CURLE_OK)
            {
                fprintf(stderr, "curl_easy_perform() failed: %s\n",
                        curl_easy_strerror(res));
            }
            else if (json["code"] != 0)
            {
                std::cout << "return code not zero" << std::endl;
            }
            else
            {
                ok = true;
            }

            curl_easy_cleanup(curl);

            curl_formfree(formpost);

            curl_slist_free_all(headerlist);
        }
        return ok;
    }

get

CURL *curl = curl_easy_init();
    CURLcode res;
    string readBuffer;

    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
        curl_easy_setopt(curl, CURLOPT_URL, "http://qadc-offline.bcc-szwg.baidu.com/cov/diff/lines");
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
        json req = json::object();
        req["pid"] = packageid;
        req["file"] = suffix;
        req["diffCommitId"] = diffCommitId;
        string req_s = req.dump();
        const char *data = req_s.c_str();
        // const char *data = "{\n    \"pid\":310,\n    \"file\":\"parent.cpp\",\n    \"diffCommitId\":\"aaaaaaa\"\n}";
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
        res = curl_easy_perform(curl);
        json result = json::parse(readBuffer);

        if (res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
                    curl_easy_strerror(res));
        } else if (result["code"] != 0) {
            cerr << "return code not zero" << endl;
                exit(1);
        } else if (result["data"].size() == 0 || result["diffLines"] == NULL) {
        
        } else {
            for (int i : result["data"][0]["diffLines"]) {
                // cout<<"# i:"<<i<<endl;
                g_ins_line.insert(i);
            }
        }
    }
    curl_easy_cleanup(curl);