2012-02-23 36 views
0

在使用libcurl實現Amazon S3訪問庫的項目中,我遇到了UTF8問題。列出存儲桶內容的方法會將相應的請求發送到S3服務器,並進行正確簽名和全部。我收到一個xml文檔,但數據已損壞。由於下載由libcurl收到的utf8編碼的xml數據而導致的字符串損壞

我將它保存到std :: string中。 例如,它開始與下面的片段:

<?xml version="1.0" encoding="UTF-8"?> 
<ListBucketResult 

「ListBucketResult」的最後的「T」之後,有一個「0」(零)中的代碼,終止所述的std :: string。在調試器中查看字符串的內容或者將它們寫入文件顯示了這一點,並且在不同的位置上有更多的零,例如,在一些(但不是全部)「>」右括號。

我使用運行在WinXP上的MS Visual Studio 2008,該項目是用unicode支持編譯的。

我應該怎麼做才能在std :: string內部接收正確的UTF8(根據幾個來源,這應該是unicode不可知的)?任何提示在這一個?

bool Http::Download(std::string& url, std::string& targetString, std::vector<std::string>* customHeaders) 
{ 
    CURLcode result = CURLE_FAILED_INIT; 
    dl = true; 

    if (curl) 
    { 
     curl = curl_easy_init(); 

     curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); 
     curl_easy_setopt(curl, CURLOPT_HEADER, 0); 
     curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteData); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &targetString); 

     if (unsafe) 
     { 
      curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 
      curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); 
     } 

     if (customHeaders) 
     { 
      curl_slist* headers = 0; 

      for (std::vector<std::string>::const_iterator iter = customHeaders->begin(); iter != customHeaders->end(); iter++) 
      { 
       headers = curl_slist_append(headers, (*iter).c_str()); 
       headers = curl_slist_append(headers, "\n"); 
      } 

      curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); 
     } 

     result = curl_easy_perform(curl); 

     long http_code = 0; 
     curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); 
     lastHttpResult = static_cast<int>(http_code); 

     curl_easy_cleanup(curl); 
    } 

    return (result == CURLE_OK); 
}; 

size_t Http::WriteData(char* data, size_t size, size_t nmemb, void* target) 
{ 
    if(target) 
    { 
     reinterpret_cast<std::string*>(target)->append(data); 
     size_t len = size * nmemb; 
     return len; 
    } 

    return 0; 
}; 
+0

請張貼您的代碼。 – liwp 2012-02-23 21:35:45

+0

編輯︰添加到pastebin的鏈接 – Martin 2012-02-23 21:44:24

+0

我認爲這是太多,不想混亂這個線程。簡單的禮貌。 – Martin 2012-02-23 21:49:44

回答

1

這是很可能的,這行是問題的一部分:

reinterpret_cast<std::string*>(target)->append(data); 

data不爲NULL終止,所以誰知道你把知識應用到字符串。這種替換:

reinterpret_cast<std::string*>(target)->append(data, size * nmemb); 
+0

謝謝你的評論,但它沒有改變任何東西。 – Martin 2012-02-23 22:11:31

+0

@Martin我會嘗試通過Wireshark監控流量,並確保您實際接收的數據中沒有NULL。 – spencercw 2012-02-23 22:12:58

+0

根據Wireshark數據中沒有NULL。例如,在上面給出的片段中,數據中的空間爲0x20,而不是0x00。 – Martin 2012-02-23 22:46:57

0

在我看來,你應該叫你WriteData()功能如下:

size_t len = size * nmemb; 
reinterpret_cast<std::string*>(target)->append(data, len); 

CURLOPT_WRITEFUNCTION國libcurl的文檔:

的大小由ptr指向的數據大小乘以nmemb,它不會被零終止。

所以你不能依靠append(const char*)正確處理附加。

+0

也謝謝您。沒有改變結果。 – Martin 2012-02-23 22:11:38

相關問題