无法在CURL上发送动态邮件正文 [英] Unable to send dynamic mail body on CURL

查看:74
本文介绍了无法在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 the lines_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 the CURLOPT_READDATA option is useless in your code and also wrong (the argument must be a pointer but you are passing lines_read which is probably an int).

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆