无法在CURL上发送动态邮件正文 [英] Unable to send dynamic mail body on CURL
问题描述
我是CURL的新手,我正在尝试发送动态邮件正文。但是当我尝试在visual c ++中使用CURL lib时,我只收到一个空主题和消息正文。
请帮忙。
我尝试过:
I am new to CURL and I am trying to send a dynamic message body. But I receive only an empty subject and message body when I attempt to use CURL lib in visual c++.
Please help.
What I have tried:
<pre> size_t Process::processmail(void *ptr, size_t size, size_t nmemb, void *userp)
{
std::string a, b, c, d;
std::string arr[MAXSPACE];
std::string search = ",";
int spacePos;
int currPos = 0;
int k = 0;
int prevPos = 0;
std::string &statistics = *(static_cast<std::string*>(userp));
do
{
spacePos = statistics.find(search, currPos);
if (spacePos >= 0)
{
currPos = spacePos;
arr[k] = statistics.substr(prevPos, currPos - prevPos);
currPos++;
prevPos = currPos;
k++;
}
} while (spacePos >= 0);
arr[k] = statistics.substr(prevPos, statistics.length());
for (int i = 0; i < k; i++)
{
std::cout << arr[i] << std::endl;
}
a = arr[3];
b = arr[2];
c = arr[1];
d = arr[0];
const char *data;
time_t now = time(0);
char* dt = ctime(&now);
const char *payload_text[] = {
"Date: ", dt, "\r\n",
"To: ",mail.c_str(), "\r\n",
"From: " FROM "\r\n",
"Subject: Analysis\r\n",
"\r\n",
"This is just a test message.\r\n",
"\r\n",
"A:", a.c_str(), "\r\n",
"B:", b.c_str(), "\r\n",
"C:", c.c_str(), "\r\n",
NULL
};
if ((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
return 0;
}
data = payload_text[lines_read];
if (data) {
size_t len = strlen(data);
memcpy(ptr, data, len);
lines_read++;
return len;
}
return 0;
}
void Process::sendmail(std::string mail)
{
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *recipients = NULL;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_USERNAME, "User Name");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "Password");
curl_easy_setopt(curl, CURLOPT_URL, "smtp.hushmail.com:587");
curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem");
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
recipients = curl_slist_append(recipients, mail.c_str());
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, &Process::processmail);
curl_easy_setopt(curl, CURLOPT_READDATA, lines_read);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_slist_free_all(recipients);
curl_easy_cleanup(curl);
}
}
推荐答案
所以你采用了libcurl示例 - smtp-mail.c [ ^ ]并对其进行修改。
您的修改之一与由回调函数创建的邮件内容。所以问题显然就在那里。候选者将是lines_read
变量。但是你没有显示该变量的定义以及它用哪个值初始化的位置。
回调函数必须是静态的,因此支持通常是指针参数以允许访问到应用程序的非静态部分。它就在这里。但是你没有使用这种机制(删除了示例代码提供的相应处理)。因此设置CURLOPT_READDATA
选项在代码中是无用的,也是错误的(参数必须是指针,但是你传递lines_read
这可能是int
)。
使用C ++类,通常会传递指向类intance的指针到回调函数。然后,您可以从静态回调函数中访问类成员。为您的案例采用示例代码可能会以这种方式完成:
So you have adopted the example from libcurl example - smtp-mail.c[^] and modified it.
One of your modifications is related to the mail content which is created by the callback function. So the problem is obviously located there. A candidate would be thelines_read
variable. But you did not show the definition of that variable and where it is initialised with which value.
Callback functions must be static and support therefore usually an pointer argument to allow access to non-static parts of your application. And so it is here. But you did not use this mechanism (removed the corresponding handling provided by the example code). So setting theCURLOPT_READDATA
option is useless in your code and also wrong (the argument must be a pointer but you are passinglines_read
which is probably anint
).
With C++ classes, usually a pointer to the class intance is passed to the callback function. Then you have access to the class members from within the static callback function. Adopting the example code for your case might be done in this way:
class Process
{
// ...
protected:
int lines_read;
static size_t processmail(void *ptr, size_t size, size_t nmemb, void *userp);
};
size_t Process::processmail(void *ptr, size_t size, size_t nmemb, void *userp)
{
// Must pass 'this' pointer when setting CURLOPT_READDATA
Process *self = reinterpret_cast<Process*>(userp);
// ...
const char *data = payload_text[self->lines_read];
size_t len = data ? strlen(data) : 0;
// Check for sufficient buffer size
// This is missing in the libcurl example
if (len > nmemb * size)
len = 0;
if (len)
{
memcpy(ptr, data, len);
self->lines_read++;
}
return len;
}
void Process::sendmail(std::string mail)
{
lines_read = 0;
// ...
curl_easy_setopt(curl, CURLOPT_READDATA, this);
// ...
}
在下面回答关于我最初没有认识到的其他错误的评论和扩展解决方案。
行
Answering below comment and extending solution about an additional bug I did not recognised initially.
The line
std::string &statistics = *(static_cast<std::string*>(userp));
不能使用上述解决方案,并且无法使用初始代码。转换必须根据传递的类型 CURLOPT_READDATA
。
当使用我的解决方案传递类指针时应该是这样的:
is not working with the above solution and wasn't working with the initial code. The casting must be according to the type passed with CURLOPT_READDATA
.
When using my solution passing the class pointer it should be something like:
std::string &statistics = self->statistics;
statistics
是类
字符串
的类成员。
[/ EDIT]
when statistics
is a Process
class member of type string
.
[/EDIT]
这篇关于无法在CURL上发送动态邮件正文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!