2014-11-24 35 views
1

我正在使用libcurl和IMAP從電子郵件收件箱提取消息。我可以完全獲取消息,但我無法獲取標題字段;我的curl寫函數只返回第一行。C++ libcurl IMAP提取標題字段

這裏是我的代碼:

std::string fetchdata; 

size_t write_data(char* buf, size_t size, size_t nmemb, void* up) { 
    fetchdata.append((char*)buf, size*nmemb); 
    return size*nmemb; 
} 

int fetchmail() { 
    CURL *curl; 
    CURLcode res = CURLE_OK; 

    curl = curl_easy_init(); 
    if(curl) { 
     curl_easy_setopt(curl, CURLOPT_USERNAME, "[email protected]"); 
     curl_easy_setopt(curl, CURLOPT_PASSWORD, "mypassword"); 
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); 
     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 

     curl_easy_setopt(curl, CURLOPT_URL, "imaps://imap.gmail.com:993/INBOX"); 
     curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "UID FETCH 10 BODY[HEADER.FIELDS (To)]"); 

     res = curl_easy_perform(curl); 

     if(res != CURLE_OK) 
      fprintf(stderr, "curl_easy_perform() failed: %s\n", 

     curl_easy_strerror(res));   
     curl_easy_cleanup(curl); 
    } 

    std::ofstream outfile("C:\\Path\\fetched.txt", std::ios_base::app); 
    outfile << fetchdata; 
    outfile.close(); 

    return (int)res; 
} 

運行fetchmail輸出

* 3 FETCH (UID 10 BODY[HEADER.FIELDS (To)] {29} 

在fetched.txt。但是,這只是第一行;控制檯輸出

* 3 FETCH (UID 10 BODY[HEADER.FIELDS (To)] {29} 
To: [email protected] 

) 
A004 OK Success 

如果我修改write_data()

size_t write_data(char* buf, size_t size, size_t nmemb, void* up) { 
    fetchdata.append((char*)buf, size*nmemb); 
    std::cout << buf; 
    return size*nmemb; 
} 

它輸出

* 3 FETCH (UID 10 BODY[HEADER.FIELDS (To)] {29 
To: [email protected] 

) 
A004 OK Success 
ted. (Success) 
(Success) 
(Success) 
WRITE] INBOX selected. (Success) 
[UIDNEXT 12] Predicted next UID. 
* OK [HIGHESTMODSEQ 1759] 
A003 OK [READ-WRITE] INBOX selected. (Success) 
* OK [HIGHESTMODSEQ 1759] 
A003 OK [READ-WRITE] INBOX selected. (Success) 

這是一個問題,我write_data()buf似乎有所有的信息。

+0

write_data()函數中的'buf'參數不是空終止的,而是'cout << buf;'要求的。您正在打印周圍內存的內容。緩衝區只是原始字節,這就是爲什麼你給緩衝區大小作爲另一個參數。 – 2014-11-24 23:19:46

+0

你可以,或者你可以使用一個臨時的'std :: string'代替:'cout << string(buf,size * nmemb);' – 2014-11-24 23:23:02

+0

但是緩衝區包含我需要的東西,看起來'write_data()'是通過了錯誤的大小? – 2014-11-24 23:23:06

回答

1

write_data()函數buf參數不是空值終止,但調用cout << buf需要空終止因爲bufchar*指針。因此,您正在打印周圍內存的內容。數據只是原始字節,這就是爲什麼您將緩衝區大小作爲另一個參數。當打印buf,你有大小要考慮到,例如:

std::cout << std::string(buf, size*nmemb); 

或者:

std::cout.write(buf, size*nmemb); 

由於您使用CURLOPT_CUSTOMREQUEST,捲曲發送請求原樣,給你回服務器按原樣回覆。在這種情況下,curl無法知道請求是什麼或如何處理您的答覆。如果你想提取其中較小的部分,你將不得不自己解析答覆。

你可能想看看捲曲的文檔和示例,尤其是使用IMAP URL(閱讀RFC 5092爲完整的語法),EG的UIDSECTION參數:

curl_easy_setopt(curl, CURLOPT_URL, "imaps://imap.gmail.com:993/INBOX/;uid=10/;section=HEADER.FIELDS%20(To)"); 

這將使捲曲生成自己的FETCH請求,而無需手動使用CURLOPT_CUSTOMREQUEST。由於curl正在創建FETCH請求,因此它更可能爲您解析響應,僅將請求的標頭數據提供給您的write_data()函數,以便手動解析/剝離更少。

+0

只是讓別人不會偶然發現:curl將「; uid = XXX」參數解釋爲消息號,而不是根據規範的IMAP UID。 IOW,URL變體將發出一個簡單的FETCH,而不是UID FETCH。 – ancow 2016-03-30 10:57:23