C++ libcurl IMAP 提取标头字段

C++ libcurl IMAP fetch header fields

本文关键字:字段 提取 libcurl IMAP C++      更新时间:2023-10-16

我正在使用带有IMAP的libcurl从电子邮件收件箱中获取邮件。我可以完全获取消息,但无法获取标头字段;我的 curl 编写函数只返回第一行。

这是我的代码:

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, "myemail@gmail.com");
        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: %sn",
        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}

在获取.txt。但是,这只是第一行;控制台输出

* 3 FETCH (UID 10 BODY[HEADER.FIELDS (To)] {29}
To: laboutpost3@gmail.com
)
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: laboutpost3@gmail.com
)
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似乎掌握了所有信息。

write_data() 函数中的 buf 参数不是以 null 结尾的,但调用 cout << buf 需要 null 终止符,因为 buf 是一个char*指针。 因此,您正在打印周围内存的内容。buf数据只是原始字节,这就是为什么将缓冲区大小作为另一个参数的原因。 打印buf时,您必须考虑该尺寸,例如:

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

或者:

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

由于您使用的是 CURLOPT_CUSTOMREQUEST ,curl 按原样发送请求,并按原样返回服务器的回复。 在这种情况下,curl 没有上下文来知道请求是什么或如何为您处理回复。 如果要提取回复的较小部分,则必须自己解析回复。

您可能需要查看curl的文档和示例,特别是使用IMAP网址的UIDSECTION参数(有关完整语法,请阅读RFC 5092),例如:

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

这将允许 curl 生成自己的FETCH请求,而无需您手动使用 CURLOPT_CUSTOMREQUEST。 由于 curl 正在创建FETCH请求,因此它更有可能为您解析响应,仅将请求的标头数据提供给您的 write_data() 函数,以便它手动解析/剥离更少。