libcurl smtp发送邮件附件大小限制问题
2016-12-21 11:54
721 查看
原文链接:http://codingfan.cn/index.php/archives/14/
问题
最近项目上有自动发送邮件的需求, 便用libcurl封装了个,发送hello world是ok的, 测试attachment的时候, 发现报错:read function returned funny value, 而且只要body或者attachment超过16k左右就报错
分析过程
翻看libcurl源码找到对应位置:
调用处:
可以看出buffersize 即BUFSIZE为固定大小16348, 当满足回调函数返回值大于该数值,就会报错。
再看看回调函数的实现:
很明显, 数组的任意一项大于该值,就会出错, 也就解释了为什么body或者attachment超出16k就会报错了
既然不支持大文件(不过16k居然能算大文件), 那我们就考虑chunk up分片读, 修改成如下, 解决问题:
总结, libcurl的设计中, 默认只支持每次读取16k左右大小的buffer(包括读取smtp协议头, 消息体, 附件等), 一旦超过尺寸, 就需要考虑分片
工具源码:curlsmtp
问题
最近项目上有自动发送邮件的需求, 便用libcurl封装了个,发送hello world是ok的, 测试attachment的时候, 发现报错:read function returned funny value, 而且只要body或者attachment超过16k左右就报错
分析过程
翻看libcurl源码找到对应位置:
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp) { struct SessionHandle *data = conn->data; size_t buffersize = (size_t)bytes; ... //fread_func为用户实现的读取buffer的回调函数 nread = (int)data->set.fread_func(data->req.upload_fromhere, 1, buffersize, data->set.in); ... else if((size_t)nread > buffersize) { /* the read function returned a too large value */ *nreadp = 0; failf(data, "read function returned funny value"); return CURLE_READ_ERROR; }
调用处:
static CURLcode readwrite_upload(struct SessionHandle *data, struct connectdata *conn, struct SingleRequest *k, int *didwhat) { ... result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount); ... }
可以看出buffersize 即BUFSIZE为固定大小16348, 当满足回调函数返回值大于该数值,就会报错。
再看看回调函数的实现:
struct WriteThis { int pos; int counter; std::vector<std::string> data; }; static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp) { struct WriteThis *pooh = (struct WriteThis *)userp; const char *data; if (size*nmemb < 1) return 0; data = text[pooh->counter]; if (data) { size_t len = strlen(data); memcpy(ptr, data, len); pooh->counter++; /* advance pointer */ return len; } return 0; /* no more data left to deliver */ }
很明显, 数组的任意一项大于该值,就会出错, 也就解释了为什么body或者attachment超出16k就会报错了
既然不支持大文件(不过16k居然能算大文件), 那我们就考虑chunk up分片读, 修改成如下, 解决问题:
#define CHUNCK_SIZE 1024 * 10 size_t CurlSmtp::read_callback(void *ptr, size_t size, size_t nmemb, void *userp) { struct WriteThis *pooh = (struct WriteThis *)userp; const char *data; if(size * nmemb < 1) return 0; const std::string& str = pooh->data[pooh->counter]; if(pooh->counter < pooh->data.size()) { size_t len = str.size(); int size = len - pooh->pos; if (len < CHUNCK_SIZE || size <= CHUNCK_SIZE) { memcpy(ptr, str.c_str() + pooh->pos, size); pooh->counter++; /* advance pointer */ pooh->pos = 0; return size; } else { memcpy(ptr, str.c_str() + pooh->pos, CHUNCK_SIZE); pooh->pos += CHUNCK_SIZE; return CHUNCK_SIZE; } } return 0; }
总结, libcurl的设计中, 默认只支持每次读取16k左右大小的buffer(包括读取smtp协议头, 消息体, 附件等), 一旦超过尺寸, 就需要考虑分片
工具源码:curlsmtp
相关文章推荐
- libcurl smtp发送邮件附件大小限制问题
- 用smtp命令发送邮件附件给新浪邮箱的问题
- SMTP发送邮件附件问题已经得到解决!!!
- smtp发送邮件附件时, 如果文件名过长, 会导致附件乱码, 除了重新编译smtp以外, 限制上传文件名长度就是个简便的方法了.
- SMTP客户端邮件发送的附件小于最大消息大小,为何被拒收
- 修改Linux中发送邮件中附件大小的限制
- SQL Server2008的Database Mail发送邮件,如何设置SMTP的问题
- ASP.net下调用SmtpClient实现smtp方式邮件发送(带附件)
- javamail发送带有附件的邮件时遇到的乱码问题解决方案
- DZ论坛附件大小限制问题
- GoDaddy的SMTP发送邮件的问题及解决方法
- 关于解决Jmail发送附件和html邮件的问题
- .net附件文件上传大小限制的问题
- 使用System.Net.Mail.SmtpClient发送邮件时出现的乱码问题
- CS下判断附件格式和大小并集成邮件发送
- ASP.net下调用SmtpClient实现smtp方式邮件发送(带附件)
- 关于解决Jmail发送附件和html邮件的问题
- php smtp邮件发送的标题乱码等一系列问题
- 关于OpenSmtp邮件标题过长,附件名,用户名出现乱码问题的终及解决Dll文件
- 我的python学习之路----发送带附件邮件(基于smtp)