NAWA  0.8
Web Application Framework for C++
emailtest.cpp
Go to the documentation of this file.
1 
6 /*
7  * Copyright (C) 2019-2021 Tobias Flaig.
8  *
9  * This file is part of nawa.
10  *
11  * nawa is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License,
13  * version 3, as published by the Free Software Foundation.
14  *
15  * nawa is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with nawa. If not, see <https://www.gnu.org/licenses/>.
22  */
23 
24 #include <ctime>
25 #include <iomanip>
26 #include <nawa/Exception.h>
27 #include <nawa/application.h>
30 #include <nawa/mail/SmtpMailer.h>
31 #include <nawa/util/encoding.h>
32 #include <nawa/util/utils.h>
33 
34 using namespace nawa;
35 using namespace nawa::mail;
36 using namespace std;
37 
38 int init(AppInit& appInit) {
39  return 0;
40 }
41 
42 int handleRequest(Connection& connection) {
43  auto& resp = connection.responseStream();
44 
45  connection.setHeader("content-type", "text/plain; charset=utf-8");
46 
47  resp << "SMTP time: ";
48  time_t currentTime = time(nullptr);
49  tm ltime;
50  localtime_r(&currentTime, &ltime);
51  resp << put_time(&ltime, "%a, %e %b %Y %H:%M:%S %z") << "\r\n\r\n";
52 
53  // The replacement rules to apply
54  auto replacementRules = make_shared<ReplacementRules>();
55  replacementRules->insert({"Test", "T€st"});
56  replacementRules->insert({"email", "émail"});
57 
58  EmailAddress from("John Doe", "johndoe@example.com");
59  EmailAddress to("The Admin", "theadmin@example.com");
60 
61  // part 1: simple email
62  resp << "+++++ TEST 1: SimpleEmail +++++\r\n\r\n";
63 
64  SimpleEmail email1;
65  email1.headers()["From"] = from.get();
66  email1.headers()["To"] = to.get();
67  email1.headers()["Content-Type"] = "text/plain; charset=utf-8";
68  email1.headers()["Subject"] = encoding::makeEncodedWord("Test mail");
69  email1.text() = "Test email 'm€ssage' =@#$%^&*()===";
70  resp << email1.getRaw(replacementRules) << "\r\n\r\n";
71 
72  // part 2: MIME email
73  resp << "+++++ TEST 2: MimeEmail +++++\r\n\r\n";
74 
75  MimeEmail email2;
76  email2.headers()["From"] = from.get();
77  email2.headers()["To"] = to.get();
78  email2.headers()["Subject"] = "Test email 2";
79 
80  // text part
81  MimeEmail::MimePart textPart;
83  textPart.contentType() = "text/plain; charset=utf-8";
84  textPart.contentDisposition() = "inline";
85  textPart.partData() = "Test email 'm€ssage' =@#$%^&*()=== asjdflkasjdfoiwej sdflkawjefijwefijsldjf dsnvndvjnwkjenggfweg";
86 
87  // html part
88  MimeEmail::MimePart htmlPart;
90  htmlPart.contentType() = "text/html; charset=utf-8";
91  htmlPart.contentDisposition() = "inline";
92  htmlPart.allowReplacements() = true;
93  htmlPart.partData() = "<html><head><title>Bla</title></head>\n<body><p>Test T&auml;st email</p></body></html>";
94 
95  // attachment
96  MimeEmail::MimePart attachmentPart;
98  attachmentPart.contentType() = "image/png; name=test.png";
99  attachmentPart.contentDisposition() = "attachment; filename=test.png";
100  try {
101  attachmentPart.partData() = utils::getFileContents("/home/tobias/Pictures/testimage.png");
102  } catch (Exception const& e) {
103  resp << "!!! Specified image file could not be loaded: " << e.getMessage() << " !!!\r\n\r\n";
104  }
105 
106  // create an alternative-type MIME container for text and html
107  MimeEmail::MimePartList textAndHtml;
109  textAndHtml.mimeParts().emplace_back(textPart);
110  textAndHtml.mimeParts().emplace_back(htmlPart);
111 
112  // add the text/html alternative-type container and the attachment to an outer mixed-type container
114  email2.mimePartList().mimeParts().emplace_back(textAndHtml);
115  email2.mimePartList().mimeParts().emplace_back(attachmentPart);
116 
117  // print the result
118  resp << email2.getRaw(replacementRules);
119 
120  // if GET sendit=yes, then send it via SMTP localhost
121  if (connection.request().get()["sendit"] == "yes") {
122 
123  resp << "\r\n";
124 
125  // connect to an SMTP server - default is localhost:25 without TLS (good for use on live web/mail servers only)
126  mail::SmtpMailer smtp("example.com", 587, mail::SmtpMailer::TlsMode::REQUIRE_STARTTLS,
127  true, "test@example.com", "12345");
128  smtp.enqueue(make_shared<SimpleEmail>(email1), to, make_shared<EmailAddress>(from), replacementRules);
129  smtp.enqueue(make_shared<MimeEmail>(email2), to, make_shared<EmailAddress>(from), replacementRules);
130 
131  try {
132  smtp.processQueue();
133  resp << "Mail sent successfully!";
134  } catch (Exception const& e) {
135  resp << "Error sending mail: " << e.getDebugMessage();
136  }
137  }
138 
139  return 0;
140 }
Exception class that can be used by apps to catch errors resulting from nawa function calls.
Structure representing a MIME email.
Structure representing a basic email.
For establishing a connection to an SMTP server and sending emails.
void setHeader(std::string key, std::string value)
Definition: Connection.cpp:218
std::ostream & responseStream() noexcept
Definition: Connection.cpp:377
nawa::Request const & request() const noexcept
Definition: Connection.cpp:357
virtual std::string getMessage() const noexcept
Definition: Exception.h:71
virtual std::string getDebugMessage() const noexcept
Definition: Exception.h:79
request::GPC const & get() const noexcept
Definition: Request.cpp:52
std::string get(bool includeName=true, bool applyPunycode=true) const
HeadersMap & headers() noexcept
MultipartType & multipartType() noexcept
std::vector< MimePartOrList > & mimeParts() noexcept
std::string & contentDisposition() noexcept
std::string & partData() noexcept
ApplyEncoding & applyEncoding() noexcept
std::string & contentType() noexcept
bool & allowReplacements() noexcept
std::string getRaw(std::shared_ptr< ReplacementRules > const &replacementRules) const override
MimePartList & mimePartList() noexcept
std::string & text() noexcept
std::string getRaw(std::shared_ptr< ReplacementRules > const &replacementRules) const override
Definition: SimpleEmail.cpp:53
int handleRequest(Connection &connection)
Definition: emailtest.cpp:42
int init(AppInit &appInit)
Definition: emailtest.cpp:38
Namespace containing functions for text encoding and decoding.
std::string makeEncodedWord(std::string const &input, bool base64=false, bool onlyIfNecessary=true)
Definition: encoding.cpp:339
std::string getFileContents(std::string const &path)
Definition: utils.cpp:493
Definition: AppInit.h:31
Contains useful functions that improve the readability and facilitate maintenance of the NAWA code.