双11狂欢大促

盲盒赢 定制羽绒服

开启惊喜盲盒,抽取你的专属好礼

— 惊喜奖品抢先看 —

使用LibCurl库的一些疑问

xdayong xdayong 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
我使用libCurl的Pop3功能,连上邮箱后,获取邮箱列表,但是在CURLOPT_WRITEFUNCTION的回调函数里,内存指向的数据正确,但是获取的长度跟实际长度不相符,例如我的邮箱里有2封未读邮件,回调函数里,指向的内存数据为:31 20 33 36 36 34 0d 0a 32 20 31 38 35 38 0d 0a 2e 0d 0a(1 3664 和 2 1858),但是回调函数里第二个参数和第三个参数分别是 1和6 ,按照官方给出的方法,计算出来的数据长度是1*6=6 ,但实际有效长度应该是19(如果除去CRLF和'.',那么实际长度应该是12)

跟踪curl的源码,发觉在Curl_pop3_write里面,获取的实际长度也是19,但是在解析过程中,发现只解析到第一个CRLF就开始使用回调,造成获取的参数不对。

由于对pop3的协议不是很了解,看这个代码也不知道该如何修改。希望有知道的人可以指点一下。

下面附上Curl解析数据时,调用上层回调的源码,它是通过Curl_client_write来调用回调函数的

CURLcode Curl_pop3_write(struct connectdata* conn, char* str, size_t nread)
{
/* This code could be made into a special function in the handler struct */
CURLcode result = CURLE_OK;
struct Curl_easy* data = conn->data;
struct SingleRequest* k = &data->req;

struct pop3_conn* pop3c = &conn->proto.pop3c;
bool strip_dot = FALSE;
size_t last = 0;
size_t i;

/* Search through the buffer looking for the end-of-body marker which is
5 bytes (0d 0a 2e 0d 0a). Note that a line starting with a dot matches
the eob so the server will have prefixed it with an extra dot which we
need to strip out. Additionally the marker could of course be spread out
over 5 different data chunks. */
for (i = 0; i < nread-1; i++) {
size_t prev = pop3c->eob;

switch (str[i]) {
case 0x0d:
if (pop3c->eob == 0) {
pop3c->eob++;

if (i) {
/* Write out the body part that didn't match */
result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
i - last);

if (result)
return result;

last = i;
}
}
else if (pop3c->eob == 3)
pop3c->eob++;
else
/* If the character match wasn't at position 0 or 3 then restart the
pattern matching */
pop3c->eob = 1;
break;

case 0x0a:
if (pop3c->eob == 1 || pop3c->eob == 4)
pop3c->eob++;
else
/* If the character match wasn't at position 1 or 4 then start the
search again */
pop3c->eob = 0;
break;

case 0x2e:
if (pop3c->eob == 2)
pop3c->eob++;
else if (pop3c->eob == 3) {
/* We have an extra dot after the CRLF which we need to strip off */
strip_dot = TRUE;
pop3c->eob = 0;
}
else
/* If the character match wasn't at position 2 then start the search
again */
pop3c->eob = 0;
break;

default:
pop3c->eob = 0;
break;
}

/* Did we have a partial match which has subsequently failed? */
if (prev && prev >= pop3c->eob) {
/* Strip can only be non-zero for the very first mismatch after CRLF
and then both prev and strip are equal and nothing will be output
below */
while (prev && pop3c->strip) {
prev--;
pop3c->strip--;
}

if (prev) {
/* If the partial match was the CRLF and dot then only write the CRLF
as the server would have inserted the dot */
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char*)POP3_EOB,
strip_dot ? prev - 1 : prev);

if (result)
return result;

last = i;
strip_dot = FALSE;
}
}
}

if (pop3c->eob == POP3_EOB_LEN) {
/* We have a full match so the transfer is done, however we must transfer
the CRLF at the start of the EOB as this is considered to be part of the
message as per RFC-1939, sect. 3 */
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char*)POP3_EOB, 2);

k->keepon &= ~KEEP_RECV;
pop3c->eob = 0;

return result;
}

if (pop3c->eob)
/* While EOB is matching nothing should be output */
return CURLE_OK;

if (nread - last) {
result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
nread - last);
}

return result;
}
...全文

相关推荐

评论 6
收藏 已收藏
分享
返回顶部
xdayong
工具平台和程序库 24,850 成员 27,330 内容