#pragma once #include "../acl_cpp_define.hpp" #include "../stdlib/string.hpp" #include "../stdlib/noncopyable.hpp" #include #if !defined(ACL_MIME_DISABLE) namespace acl { class dbuf_pool; struct rfc822_addr; class mail_attach; class mail_body; class ofstream; /** * 邮件数据构造类,此类可以生成一封完整的邮件,同时还用于构建 SMTP 发送过程 * 的邮件信封信息 */ class ACL_CPP_API mail_message : public noncopyable { public: /** * 构造函数 * @param charset {const char*} 字符集 */ mail_message(const char* charset = "utf-8"); ~mail_message(); /** * 设置 SMTP 发送过程的身份验证信息 * @param user {const char*} 邮箱账号 * @param pass {const char*} 邮箱密码 * @return {mail_message&} */ mail_message& set_auth(const char* user, const char* pass); /** * 设置邮件的发送都邮箱,此字段可用于 SMTP 发送过程的 MAIL FROM 命令, * 同时又可作为邮件头中的 From 字段值 * @param from {const char*} 发件人邮件地址 * @param name {const char*} 发件人名称 * @return {mail_message&} */ mail_message& set_from(const char* from, const char* name = NULL); mail_message& set_sender(const char* sender, const char* name = NULL); /** * 设置邮件头中的 Reply-To 字段值 * @param reply_to {const char*} Reply-To 邮箱字段值 * @param name {const char*} Reply-To 对应的人员名称 * @return {mail_message&} */ mail_message& set_reply_to(const char* reply_to, const char* name = NULL); /** * 设置邮件头中的 Return-Path 字段值 * @param return_path {const char*} Return-Path 邮箱字段值 * @return {mail_message&} */ mail_message& set_return_path(const char* return_path); /** * 设置邮件头中的 Delivered-To 字段值 * @param delivered_to {const char*} Delivered-To 邮箱字段值 * @return {mail_message&} */ mail_message& set_delivered_to(const char* delivered_to); /** * 添加收件人地址,该地址仅出现在信封中,不出现在邮件头中 * @param recipients {const char*} 收件人集合,遵守 RFC822 格式 * @return {mail_message&} */ mail_message& add_recipients(const char* recipients); /** * 设置邮件头中的 To 字段值,同时该收件人地址集合被用于信封中作为收件人 * @param to {const char*} 收件人邮箱地址集合,遵守 RFC822 格式 * @return {mail_message&} */ mail_message& add_to(const char* to); /** * 设置邮件头中的 Cc 字段值,同时该收件人地址集合被用于信封中作为收件人 * @param cc {const char*} 收件人邮箱地址集合,遵守 RFC822 格式 * @return {mail_message&} */ mail_message& add_cc(const char* cc); /** * 设置邮件发送的暗送地址集合,该地址集合不会出现在邮件头中 * @param bcc {const char*} 暗送邮箱地址集合,遵守 RFC822 格式 * @return {mail_message&} */ mail_message& add_bcc(const char* bcc); /** * 设置邮件头中的主题,该主题将采用 rfc2047 编码且采用类构造函数 * 设置的字符集 * @param subject {const char*} 邮件头主题字段值 * @return {mail_message&} */ mail_message& set_subject(const char* subject); /** * 用户可以调用此函数添加邮件头中的头部扩展字段值 * @param name {const char*} 字段名 * @param value {const char*} 字段值 * @return {mail_message&} */ mail_message& add_header(const char* name, const char* value); /** * 设置邮件的正文对象 * @param body {const mail_body&} 邮件正文对象 * @return {mail_message&} */ mail_message& set_body(const mail_body& body); /** * 给一封邮件添加一个附件 * @param filepath {const char*} 附件全路径(非空) * @param content_type {const char*} 附件类型(非空) * @return {mail_message&} */ mail_message& add_attachment(const char* filepath, const char* content_type); /** * 构造一封完整的邮件,并将邮件内容存储于给定磁盘文件中,如果该文件 * 存在则首先会清空,否则会创建新的文件 * @param filepath {const char*} 目标文件 * @return {bool} 操作是否成功 */ bool save_to(const char* filepath); /** * 可以单独调用本函数用来生成邮件头数据 * @param out {string&} 创建的邮件头数据将追加于该缓冲区中 * @return {bool} 操作是否成功 */ bool build_header(string& out); /** * 获得所创建的邮件在磁盘上的全路径,该函数必须在调用 save_to 成功后调用 * @return {const char*} */ const char* get_email() const { return filepath_; } /** * 获得用于 SMTP 身份验证时的邮箱账号 * @return {const char*} */ const char* get_auth_user() const { return auth_user_; } /** * 获得用于 SMTP 身份验证时的邮箱账号密码 * @return {const char*} */ const char* get_auth_pass() const { return auth_pass_; } /** * 获得由 set_from 设置的邮箱地址对象 * @return {const rfc822_addr*} */ const rfc822_addr* get_from() const { return from_; } /** * 获得由 set_sender 设置的邮箱地址对象 * @return {const rfc822_addr*} */ const rfc822_addr* get_sender() const { return sender_; } /** * 获得由 set_reply_to 设置的邮箱地址对象 * @return {const rfc822_addr*} */ const rfc822_addr* get_reply_to() const { return reply_to_; } /** * 获得由 set_return_path 设置的邮箱地址对象 * @return {const rfc822_addr*} */ const rfc822_addr* get_return_path() const { return return_path_; } /** * 获得由 set_delivered_to 设置的邮箱地址对象 * @return {const rfc822_addr*} */ const rfc822_addr* get_delivered_to() const { return delivered_to_; } const std::vector& get_to() const { return to_list_; } /** * 获得由 set_cc 设置的邮箱地址对象集合 * @return {const std::vector&} */ const std::vector& get_cc() const { return cc_list_; } /** * 获得由 set_bcc 设置的邮箱地址对象集合 * @return {const std::vector&} */ const std::vector& get_bcc() const { return bcc_list_; } /** * 获得所有邮件接收者的地址集合 * @return {const std::vector&} */ const std::vector& get_recipients() const { return recipients_; } /** * 获得用户设置的邮件头扩展字段值 * @param name {const char*} 字段名 * @return {const char*} */ const char* get_header_value(const char* name) const; /** * 为 MIME 数据创建唯一的分隔符 * @param id {const char*} 调用者填写的 ID 标识 * @param out {string&} 存储结果 */ static void create_boundary(const char* id, string& out); private: dbuf_pool* dbuf_; char* charset_; char* transfer_encoding_; char* auth_user_; char* auth_pass_; rfc822_addr* from_; rfc822_addr* sender_; rfc822_addr* reply_to_; rfc822_addr* return_path_; rfc822_addr* delivered_to_; std::vector to_list_; std::vector cc_list_; std::vector bcc_list_; std::vector recipients_; char* subject_; std::vector > headers_; std::vector attachments_; const mail_body* body_; size_t body_len_; char* filepath_; void add_addrs(const char* in, std::vector& out); bool append_addr(const rfc822_addr& addr, string& out); bool append_addr(const char* name, const rfc822_addr& addr, string& out); bool append_addrs(const char* name, const std::vector& addrs, string& out); bool append_message_id(string& out); bool append_subject(const char* subject, string& out); bool append_date(string& out); bool append_header(ofstream& fp); bool append_multipart(ofstream& fp); }; } // namespace acl #endif // !defined(ACL_MIME_DISABLE)