c - 通过 C libcurl 访问 gmail imaps 服务器失败

标签 c linux libcurl gmail-imap

我正在使用 libcurl C 库访问(获取、搜索)gmail imaps 服务器,我正在使用 libcurl 示例中的代码,即“imap-ssl.c”作为测试示例。示例代码在第一次执行时运行良好,并从我的 gmail 帐户中获取了所需的电子邮件,但是当您尝试再次执行该程序时,当有人想要获取不同的电子邮件或再次获取相同的电子邮件时,它会失败, 但如果我在大约 20 分钟后重新运行该程序,它就会工作并获取所需的邮件。

似乎 gmail 要求我们立即从服务器获取整个收件箱,即本地(获取的)电子邮件与在线 gmail 服务器的同步只允许每 20 分钟一次或什么。???如果一个人只想一次访问一封电子邮件,或者只是一封一封地浏览他的整个 Gmail 收件箱邮件怎么办?

我还尝试使用 openssl 命令行工具在 imap.gmail.com:993(启用 ssl)上获取或执行 imaps 命令,它就像一个魅力,无论我尝试访问 gmail 多少次,它永远不会麻烦说一句,但 libcurl 会。

这是示例 C 代码:

#include<stdio.h>
#include<string.h>
#include <curl/curl.h>

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

curl = curl_easy_init();
if(curl) {
/* Set username and password */
curl_easy_setopt(curl, CURLOPT_USERNAME, "example@gmail.com");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "examplepassword");

/* This will fetch message 1 from the user's inbox. Note the use of
* imaps:// rather than imap:// to request a SSL based connection. */
curl_easy_setopt(curl, CURLOPT_URL,"imaps://imap.gmail.com:993/INBOX/;UID=5");
/* Note: CA cert is already in the right place (checked) */

#ifdef SKIP_PEER_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif

/* If the site you're connecting to uses a different host name that what
* they have mentioned in their server certificate's commonName (or
* subjectAltName) fields, libcurl will refuse to connect. You can skip
* this check, but this will make the connection less secure. */
#ifdef SKIP_HOSTNAME_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif

curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* Perform the fetch */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));  
curl_easy_cleanup(curl);
}
return (int)res;
}

这是它给我的错误/日志:

第一次运行程序时(或20分钟后):

> * Hostname was NOT found in DNS cache
> *   Trying 74.125.206.109...
> * Connected to imap.gmail.com (74.125.206.109) port 993 (#0)
> * successfully set certificate verify locations:
> *   CAfile: none
> >  CApath: /etc/ssl/certs
> * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
> * Server certificate:
> *      subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=imap.gmail.com
> *      start date: 2017-03-22 16:46:00 GMT
> *      expire date: 2017-06-14 16:17:00 GMT
> *      subjectAltName: imap.gmail.com matched
> *      issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
> *      SSL certificate verify ok.
> * OK Gimap ready for requests from 182.180.90.60 
> * A001 CAPABILITY
> >      CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN
> AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH A001 OK Thats all
> she wrote! 9
> * A002 AUTHENTICATE PLAIN 
> * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH
> UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE
> APPENDLIMIT=35651584
> * A002 OK example@gmail.com authenticated (Success)
> * A003 SELECT INBOX
> * FLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing)
> * OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing \*)] Flags permitted.
> * OK [UIDVALIDITY 1] UIDs valid.
> * 32 EXISTS
> * 0 RECENT
> * OK [UIDNEXT 46] Predicted next UID.
> * OK [HIGHESTMODSEQ 4777]
> * A003 OK [READ-WRITE] INBOX selected. (Success)
> * A004 FETCH 5 BODY[]
> * 5 FETCH (BODY[] {628}
> *Found 628 bytes to download
> >   Bcc: example@gmail.com
> >   Return-Path: <example@gmail.com>
> >   Received: from localhost (["MY IP Address])
> >   by smtp.gmail.com with ESMTPSA id 
> >   for <example@gmail.com>
> >   (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
> >   Wed, 15 Mar 2017 03:13:29 -0700 (PDT)
> * Message-ID: <"msg id"@mx.google.com>
> * Date: Wed, 15 Mar 2017 03:13:29 -0700 (PDT)
> * From: example@gmail.com
> >     Written 489 bytes, 139 bytes are left for transfer
> >     Hi, i'm using openssl to send this message, i hope you are doing great man
> >     Thank you so much
> >     I just wanted to tell you that this is also possible
> *  A004 OK Success
> * Connection #0 to host imap.gmail.com left intact

当尝试在成功获取后立即重新运行程序时:

> * Hostname was NOT found in DNS cache
> *   Trying 74.125.133.108...
> *   Trying 2a00:1450:400c:c07::6d...
> * connect to 2a00:1450:400c:c07::6d port 993 failed: Network is unreachable
>* Failed to connect to imap.gmail.com port 993: Network is unreachable
>* Closing connection 0
>>curl_easy_perform() failed: Couldn't connect to server

任何代码示例都将不胜感激。

P.S: 添加了代码

最佳答案

在第二次尝试时,它无法连接到 imap 服务器,但这与 libcurl 无关。

您可以添加以下代码以确保它仅通过 IPv4 连接,然后调试输出中的错误消息将来自与您更相关的 IPv4 地址的连接尝试(因为您很可能不有 IPv6 支持):

curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

有关该选项的更多信息,请参见: https://curl.haxx.se/libcurl/c/CURLOPT_IPRESOLVE.html

在 libcurl 程序无法运行期间,尝试连接到与 libcurl 程序尝试通过 telnet 连接到的 IP 完全相同的端口 993。我相信它也会失败。

前进的方向可能是调查您是否有某种可能导致问题的防火墙。尝试运行 tcpdump(如果需要 GUI,则运行 wireshark)以查看在 TCP 级别发生了什么。

关于c - 通过 C libcurl 访问 gmail imaps 服务器失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43055263/

相关文章:

linux - 带有 gcc 4.1.2 的 Centos openmp

c - libcurl:如何使用原始文件名下载 url? (相当于 "-O/--remote-name")

c - 我应该在异常终止时释放分配的内存吗?

c - C中的内存管理

python - 如何更改 Linux 上 Python 的默认版本以便安装和使用某些模块?

Windows 上的 curl/curl.h

c++ - 调试 CURLOPT_POSTFIELDS 网址?

c - 有什么办法可以输入 "destringify"以便它可以像标识符一样使用吗?

c - 有没有像 npm 或 apt-get 这样的 cpm?

具有动态 IP 的 MySQL 复制多主机到单个从机