NAWA 0.9
Web Application Framework for C++
emailtest.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2019-2022 Tobias Flaig.
3 *
4 * This file is part of nawa.
5 *
6 * nawa is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License,
8 * version 3, as published by the Free Software Foundation.
9 *
10 * nawa is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with nawa. If not, see <https://www.gnu.org/licenses/>.
17 */
18
24#include <ctime>
25#include <iomanip>
26#include <nawa/Exception.h>
27#include <nawa/application.h>
31#include <nawa/util/encoding.h>
32#include <nawa/util/utils.h>
33
34using namespace nawa;
35using namespace nawa::mail;
36using namespace std;
37
38int init(AppInit& appInit) {
39 return 0;
40}
41
42int 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;
82 textPart.applyEncoding() = MimeEmail::MimePart::ApplyEncoding::QUOTED_PRINTABLE;
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;
89 htmlPart.applyEncoding() = MimeEmail::MimePart::ApplyEncoding::QUOTED_PRINTABLE;
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;
97 attachmentPart.applyEncoding() = MimeEmail::MimePart::ApplyEncoding::BASE64;
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;
108 textAndHtml.multipartType() = MimeEmail::MimePartList::MultipartType::ALTERNATIVE;
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
113 email2.mimePartList().multipartType() = MimeEmail::MimePartList::MultipartType::MIXED;
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.
This file will be configured by CMake and contains the necessary properties to ensure that a loaded a...
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
std::vector< MimePartOrList > & mimeParts() noexcept
MultipartType & multipartType() noexcept
std::string & contentDisposition() noexcept
std::string & partData() noexcept
bool & allowReplacements() noexcept
std::string & contentType() noexcept
ApplyEncoding & applyEncoding() noexcept
MimePartList & mimePartList() noexcept
std::string getRaw(std::shared_ptr< ReplacementRules > const &replacementRules) const override
std::string getRaw(std::shared_ptr< ReplacementRules > const &replacementRules) const override
Definition: SimpleEmail.cpp:53
std::string & text() noexcept
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.