【问题标题】:C++ libcurl IMAP fetch header fieldsC++ libcurl IMAP 获取头字段
【发布时间】:2014-11-25 10:40:55
【问题描述】:

我正在使用带有 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: %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: 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 参数不是以空值结尾的,但cout &lt;&lt; buf; 需要它。您正在打印周围内存的内容。缓冲区只是原始字节,这就是为什么将缓冲区大小作为另一个参数给出的原因。
  • 你可以,或者你可以使用临时 std::string 代替:cout &lt;&lt; string(buf, size*nmemb);
  • 但是缓冲区包含我需要的东西,似乎write_data()传递的大小错误?
  • @RemyLebeau 我想要第一行之后的东西,而不是全部。
  • 由于您使用的是CURLOPT_CUSTOMREQUEST,curl 只能将服务器的全部回复提供给您,因为它没有上下文来知道请求是什么或如何为您处理回复。如果您想提取更小的部分,则必须自己解析回复。

标签: c++ curl imap libcurl


【解决方案1】:

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

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

或者:

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

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

您可能想查看 curl 的文档和示例,特别是使用 IMAP url 的 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() 函数,因此它无需手动解析/剥离。

【讨论】:

  • 只是为了让其他人不会对此感到困惑:curl 将“;uid=XXX”参数解释为消息编号,而不是按照规范的 IMAP UID。 IOW,URL 变体将发出一个简单的 FETCH,而不是 UID FETCH。
猜你喜欢
  • 1970-01-01
  • 2020-01-18
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
相关资源
最近更新 更多