int S3fsCurl::PreMultipartPostRequest()

in src/curl.cpp [3548:3660]


int S3fsCurl::PreMultipartPostRequest(const char* tpath, headers_t& meta, std::string& upload_id, bool is_copy)
{
    S3FS_PRN_INFO3("[tpath=%s]", SAFESTRPTR(tpath));

    if(!tpath){
        return -EINVAL;
    }
    if(!CreateCurlHandle()){
        return -EIO;
    }
    std::string resource;
    std::string turl;
    MakeUrlResource(get_realpath(tpath).c_str(), resource, turl);

    query_string   = "uploads";
    turl          += "?" + query_string;
    url            = prepare_url(turl.c_str());
    path           = get_realpath(tpath);
    requestHeaders = NULL;
    bodydata.clear();
    responseHeaders.clear();

    std::string contype = S3fsCurl::LookupMimeType(std::string(tpath));

    for(headers_t::iterator iter = meta.begin(); iter != meta.end(); ++iter){
        std::string key   = lower(iter->first);
        std::string value = iter->second;
        if(is_prefix(key.c_str(), "x-oss-object-acl")){
            // not set value, but after set it.
        }else if(is_prefix(key.c_str(), "x-oss-meta")){
            requestHeaders = curl_slist_sort_insert(requestHeaders, iter->first.c_str(), value.c_str());
        }else if(key == "x-oss-server-side-encryption" && value != "KMS"){
            // Only copy mode.
            if(is_copy && !AddSseRequestHead(sse_type_t::SSE_OSS, value, false, true)){
                S3FS_PRN_WARN("Failed to insert SSE-OSS header.");
            }
        }else if(key == "x-oss-server-side-encryption-key-id"){
            // Only copy mode.
            if(is_copy && !value.empty() && !AddSseRequestHead(sse_type_t::SSE_KMS, value, false, true)){
                S3FS_PRN_WARN("Failed to insert SSE-KMS header.");
            }
        }else if(key == "x-oss-server-side-encryption-customer-key-md5"){
            // Only copy mode.
            if(is_copy){
                if(!AddSseRequestHead(sse_type_t::SSE_C, value, true, true) || !AddSseRequestHead(sse_type_t::SSE_C, value, true, false)){
                    S3FS_PRN_WARN("Failed to insert SSE-C header.");
                }
            }
        }
    }
    // "x-oss-object-acl", storage class, sse
    if(S3fsCurl::default_acl != acl_t::DEFAULT){
        requestHeaders = curl_slist_sort_insert(requestHeaders, "x-oss-object-acl", S3fsCurl::default_acl.str());
    }
    if(strcasecmp(GetStorageClass().c_str(), "STANDARD") != 0){
        requestHeaders = curl_slist_sort_insert(requestHeaders, "x-oss-storage-class", GetStorageClass().c_str());
    }
    // SSE
    if(!is_copy){
        std::string ssevalue;
        if(!AddSseRequestHead(S3fsCurl::GetSseType(), ssevalue, false, false)){
            S3FS_PRN_WARN("Failed to set SSE header, but continue...");
        }
    }
    if(is_use_ahbe){
        // set additional header by ahbe conf
        requestHeaders = AdditionalHeader::get()->AddHeader(requestHeaders, tpath);
    }

    requestHeaders = curl_slist_sort_insert(requestHeaders, "Accept", NULL);
    requestHeaders = curl_slist_sort_insert(requestHeaders, "Content-Type", contype.c_str());

    op = "POST";
    type = REQTYPE_PREMULTIPOST;

    // setopt
    if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_URL, url.c_str())){
        return -EIO;
    }
    if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_POST, true)){              // POST
        return -EIO;
    }
    if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void*)&bodydata)){
        return -EIO;
    }
    if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback)){
        return -EIO;
    }
    if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_POSTFIELDSIZE, 0)){
        return -EIO;
    }
    if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_INFILESIZE, 0)){           // Content-Length
        return -EIO;
    }
    if(!S3fsCurl::AddUserAgent(hCurl)){                            // put User-Agent
        return -EIO;
    }

    // request
    int result;
    if(0 != (result = RequestPerform())){
        bodydata.clear();
        return result;
    }

    if(!simple_parse_xml(bodydata.c_str(), bodydata.size(), "UploadId", upload_id)){
        bodydata.clear();
        return -EIO;
    }

    bodydata.clear();
    return 0;
}