2012-02-23 35 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

相关问题