libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
curl.hpp
Go to the documentation of this file.
1 #ifndef LIBJMMCG_UNIX_CURL_HPP
2 #define LIBJMMCG_UNIX_CURL_HPP
3 
4 /******************************************************************************
5 ** Copyright © 2017 by J.M.McGuiness, coder@hussar.me.uk
6 **
7 ** This library is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU Lesser General Public
9 ** License as published by the Free Software Foundation; either
10 ** version 2.1 of the License, or (at your option) any later version.
11 **
12 ** This library is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ** Lesser General Public License for more details.
16 **
17 ** You should have received a copy of the GNU Lesser General Public
18 ** License along with this library; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 
22 #include "core/config.h"
23 
24 #include <boost/noncopyable.hpp>
25 
26 #include <list>
27 #include <sstream>
28 #include <string>
29 #include <vector>
30 
31 #include <curl/curl.h>
32 
33 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE {
34 
35  /**
36  * <a href="https://curl.haxx.se/libcurl/c/libcurl-tutorial.html">Curl tutorial</a>.
37  */
38  class curl : boost::noncopyable {
39  public:
42 
43  class email_recipients : boost::noncopyable {
44  public:
45  ~email_recipients() noexcept(true);
46 
47  /**
48  Add two recipients, in this particular case they correspond to the To: and Cc: addressees in the header, but they could be any kind of recipient.
49  */
50  void push_back(std::string const &addr) noexcept(true);
51  bool empty() const noexcept(true);
52 
53  private:
54  friend class curl;
55 
56  curl_slist * recipients_=nullptr;
57  recipients_t addrs_;
58  };
59 
60  /**
61  \param smtp_url The hostname:port to which the email should be sent.
62  */
63  curl(std::string const &smtp_url, unsigned short port, std::string const &username, std::string const &password, bool enable_logging, bool enable_ssl_verification=false) noexcept(false);
64  ~curl() noexcept(true);
65 
66  /**
67  Note that this option isn't strictly required, omitting it will result in libcurl sending the MAIL FROM command with empty sender data. All autoresponses should have an empty reverse-path, and should be directed to the address in the reverse-path which triggered them. Otherwise, they could cause an endless loop. See RFC 5321 Section 4.5.5 for more details.
68  */
69  void from(std::string const &from) noexcept(true);
70 
71  /**
72  We're using a callback function to specify the payload (the headers and body of the message). You could just use the CURLOPT_READDATA option to specify a FILE pointer to read from.
73  */
74  failures_t send(std::string const &subject, std::string const &body, recipients_t const &recipients) noexcept(false);
75 
76  friend std::ostream &operator<<(std::ostream &os, curl const &c) noexcept(false) {
77  os<<"SMTP server: '"<<c.smtp_url_<<"'"
78  ", logon username: '"<<c.username_<<"'"
79  ", from: '"<<c.from_<<"'.";
80  return os;
81  }
82 
83  private:
85  struct upload_status {
86  size_t lines_read=0;
87  };
88 
89  CURL * const handle_;
90  const std::string smtp_url_;
91  const std::string username_;
92  const std::string password_;
93  std::string from_;
94  upload_status upload_ctx_;
95 
96  static payload_message_t payload_text_strs_;
97 
98  /**
99  If your server doesn't have a valid certificate, then you can disable part of the Transport Layer Security protection by setting the CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false). That is, in general, a bad idea. It is still better than sending your authentication details in plain text though. Instead, you should get the issuer certificate (or the host certificate if the certificate is self-signed) and add it to the set of certificates that are known tolibcurl using CURLOPT_CAINFO and/or CURLOPT_CAPATH. See docs/SSLCERTS for more information.
100  */
101  void ignore_ssl_verification() noexcept(true);
102 
103  /**
104  Since the traffic will be encrypted, it is very useful to turn on debug information within libcurl to see what is happening during the transfer.
105  */
106  void set_logging() noexcept(true);
107 
108  static std::string current_time_for_email() noexcept(false);
109  void create_message(std::string const &to, std::string const &subject, std::string const &body) const noexcept(false);
110  static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp);
111  };
112 
113 } }
114 
115 #endif