使用libcurl发送带附件的电子邮件 [英] Sending Email with attachment using libcurl

查看:123
本文介绍了使用libcurl发送带附件的电子邮件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用libcurl发送一封附带c ++附件的电子邮件( http:// curl。 haxx.se/ [ ^ ])。

我可以从gmail服务器成功发送电子邮件,但不知道如何发送附件。

我使用的代码如下:



I want to send an email with attachment from c++ using libcurl( http://curl.haxx.se/[^]).
I'm able to send an email successfully from gmail server but don't know how to send with attachment.
The code I'm using is as follows:

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

#define FROM    "<xxxx@gmail.com>"
#define TO      "<xxxx@gmail.com>"

static const char *payload_text[] = {
  "To: " TO "\r\n",
  "From: " FROM "\r\n",
  "Subject: SMTP TLS example message\r\n",
  NULL
};

struct upload_status {
  int lines_read;
};

static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
{
  struct upload_status *upload_ctx = (struct upload_status *)userp;
  const char *data;

  if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
    return 0;
  }

  data = payload_text[upload_ctx->lines_read];

  if(data) {
    size_t len = strlen(data);
    memcpy(ptr, data, len);
    upload_ctx->lines_read++;

    return len;
  }

  return 0;
}

int main(void)
{
  CURL *curl;
  CURLcode res = CURLE_OK;
  struct curl_slist *recipients = NULL;
  struct upload_status upload_ctx;

  upload_ctx.lines_read = 0;

  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_USERNAME, "xxxx");
    curl_easy_setopt(curl, CURLOPT_PASSWORD, "xxxx");
    curl_easy_setopt(curl, CURLOPT_URL, "smtp://smtp.gmail.com:587");
    curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
    curl_easy_setopt(curl, CURLOPT_CAINFO, "google.pem");
    curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
    recipients = curl_slist_append(recipients, TO);
    //curl_easy_setopt(curl, CURLOPT_FILE, "edgE0DF.tmp"); 
    curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
    curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
    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);
  }
  system("pause");
  return (int)res;
}





任何建议都表示赞赏。



Any suggestion is appreciated.

推荐答案

下面的代码使用Imagemagick ++ http://www.imagemagick.org/Magick++/ [ ^ ]对base64进行编码。



The code bellow uses Imagemagick++http://www.imagemagick.org/Magick++/[^] to base64 encode the image.

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

#define FROM    "<xxxx@gmail.com>"
#define TO      "<xxxx@gmail.com>"
#define FILENAME "pic.jpg"
 
static const int CHARS= 76;			//Sending 54 chararcters at a time with \r , \n and \0 it becomes 57 and its encoded length will be 76 by the formula string_length/3*4
static const int ADD_SIZE= 7;			// ADD_SIZE for TO,FROM,SUBJECT,CONTENT-TYPE,CONTENT-TRANSFER-ENCODING,CONETNT-DISPOSITION and \r\n
static const int SEND_BUF_SIZE= 54;
static char (*fileBuf)[CHARS] = NULL;
 
struct fileBuf_upload_status 
{
  int lines_read;
};
 
size_t read_file()
{
	Magick::Image img(FILENAME);
	Magick::Blob blob;
	img.write( &blob );
	std::string encoded_buf = blob.base64();
	
	size_t encoded_buf_len = encoded_buf.size();
	size_t len(0),buffer_size(0);
	int no_of_rows = (int)ceil((double)encoded_buf.size()/SEND_BUF_SIZE) ;
	int read(0);
	fileBuf = new char[ADD_SIZE + no_of_rows + 1][CHARS];	//Extra row for our special character to be used in conditional statements,here ""
											// ADD_SIZE for TO,FROM,SUBJECT,CONTENT-TYPE,CONTENT-TRANSFER-ENCODING,CONETNT-DISPOSITION and \r\n
 
	strcpy(fileBuf[len++],"To: " TO "\r\n");
	buffer_size += strlen(fileBuf[len-1]) + 1;	// 1 for \0
	strcpy(fileBuf[len++],"From: " FROM "\r\n");
	buffer_size += strlen(fileBuf[len-1]) + 1;
	strcpy(fileBuf[len++],"Subject: SMTP TLS example message\r\n");
	buffer_size += strlen(fileBuf[len-1]) + 1;
	strcpy(fileBuf[len++],"Content-Type: image/jpeg; name=\"" FILENAME "\"\r\n");
	buffer_size += strlen(fileBuf[len-1]) + 1;
	strcpy(fileBuf[len++],"Content-Transfer-Encoding: base64\r\n");
	buffer_size += strlen(fileBuf[len-1]) + 1;
	strcpy(fileBuf[len++],"Content-Disposition: attachment; filename=\"" FILENAME "\"\r\n");
	buffer_size += strlen(fileBuf[len-1]) + 1;
	strcpy(fileBuf[len++],"\r\n");
	buffer_size += strlen(fileBuf[len-1]) + 1;
	
	int pos = 0;
	std::string sub_encoded_buf;
	for (; len < no_of_rows + ADD_SIZE; ++len)
	{		
		if (pos*54 <= encoded_buf_len)
		{
			sub_encoded_buf = encoded_buf.substr(pos*54,54);
			pos++;
 		sub_encoded_buf += "\r\n";
		memcpy(fileBuf[len],sub_encoded_buf.c_str(),sub_encoded_buf.size());
                buffer_size += sub_encoded_buf.size() ;	// 1 for \0
		}
	}
        strcpy(fileBuf[len],"");

// The following code prints the structure of the email being sent.
//	
//	for (int i=0;i<no_of_rows + ADD_SIZE;++i)
//	{
//		printf("%s",fileBuf[i]);
//	}
	return buffer_size;
}
 

static size_t fileBuf_source(void *ptr, size_t size, size_t nmemb, void *userp)
{
	struct fileBuf_upload_status *upload_ctx = (struct fileBuf_upload_status *)userp;
	const char *fdata;
 
	if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) 
	{
		return 0;
	}
 
	fdata = fileBuf[upload_ctx->lines_read];
 
	if(strcmp(fdata,"")) 
	{
		size_t len = strlen(fdata);
		memcpy(ptr, fdata, len);
		upload_ctx->lines_read++;
		return len;
	}
	return 0;
}
 
int main(void)
{
  CURL *curl;
  CURLcode res = CURLE_OK;
  struct curl_slist *recipients = NULL;
  struct fileBuf_upload_status file_upload_ctx;
  size_t file_size(0);
 
  file_upload_ctx.lines_read = 0;
 
  curl = curl_easy_init();
  file_size = read_file();
  if(curl) 
  {
    curl_easy_setopt(curl, CURLOPT_USERNAME, "xxxx");
    curl_easy_setopt(curl, CURLOPT_PASSWORD, "xxxx");
    curl_easy_setopt(curl, CURLOPT_URL, "smtp://smtp.gmail.com:587");
    curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
    //curl_easy_setopt(curl, CURLOPT_CAINFO, "google.pem");
    curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
    recipients = curl_slist_append(recipients, TO);
    curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
 
	curl_easy_setopt(curl, CURLOPT_INFILESIZE, file_size); 
	curl_easy_setopt(curl, CURLOPT_READFUNCTION, fileBuf_source);
    curl_easy_setopt(curl, CURLOPT_READDATA, &file_upload_ctx);
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
 
    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);
  }
  delete[] fileBuf;
  return (int)res;
}





使用以下命令编译



Use the following command to compile


IM_CXXFLAGS =
IM_CXXFLAGS=


(Magick ++ - config --cxxflags)
(Magick++-config --cxxflags)


这篇关于使用libcurl发送带附件的电子邮件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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