NAWA 0.9
Web Application Framework for C++
nawatest.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 <iostream>
25#include <nawa/application.h>
27#include <nawa/util/encoding.h>
28#include <unistd.h>
29
30using namespace nawa;
31using namespace std;
32
33int init(nawa::AppInit& appInit) {
34
35 // enable access filtering
36 appInit.accessFilters().filtersEnabled() = true;
37
38 // apply a forward filter for images
39 ForwardFilter forwardFilter;
40 forwardFilter.pathFilter() = {{"test", "images"},
41 {"test2", "images"}};
42 forwardFilter.extensionFilter() = {"png", "jpg", "svg"};
43 forwardFilter.basePath() = "/home/tobias/Pictures";
44 appInit.accessFilters().forwardFilters().push_back(forwardFilter);
45
46 // send 404 error for non-image files in /test{2}/images
47 BlockFilter blockFilter;
48 blockFilter.pathFilter() = {{"test", "images"},
49 {"test2", "images"}};
50 blockFilter.extensionFilter() = {"png", "jpg", "svg"};
51 blockFilter.invertExtensionFilter() = true;
52 blockFilter.status() = 404;
53 appInit.accessFilters().blockFilters().push_back(blockFilter);
54
55 // apply a block filter for everything that is not in /test{2} or /test{2}/images (and some more restrictions)
56 BlockFilter blockFilter2;
57 blockFilter2.invert() = true;
58 blockFilter2.regexFilterEnabled() = true;
59 blockFilter2.regexFilter().assign(R"(/test2?(/images)?(/[A-Za-z0-9_\-]*\.?[A-Za-z]{2,4})?)");
60 blockFilter2.status() = 404;
61 appInit.accessFilters().blockFilters().push_back(blockFilter2);
62
63 // authenticate access to the images directory
64 AuthFilter authFilter;
65 authFilter.pathFilter() = {{"test", "images"}};
66 authFilter.authName() = "Not for everyone!";
67 authFilter.authFunction() = [](string user, string password) -> bool {
68 return (user == "test" && password == "supersecure");
69 };
70 appInit.accessFilters().authFilters().push_back(authFilter);
71
72 return 0;
73}
74
75int handleRequest(Connection& connection) {
76
77 auto& resp = connection.responseStream();
78 auto& req = connection.request();
79 auto& session = connection.session();
80
81 // start a session
82 session.start();
83
84 connection.setCookie("TEST", "test");
85 connection.setCookiePolicy(Cookie().httpOnly(true));
86
87 string encoded = R"(&lt;input type=&quot;text&quot; value=&quot;t&auml;&Aopf;&#x1D538;&#120120;st&quot;&gt;)";
88 string decoded = R"(<input type="text" value="tä𝔸𝔸𝔸st">)";
89
90 resp << "<!DOCTYPE html>\n"
91 "<html><head><title>Test</title></head><body>"
92 "<p>Hello World! HTML string: "
93 << encoding::htmlEncode(decoded, true) << "</p>"
94 "<p>Client IP: "
95 << encoding::htmlEncode(req.env()["REMOTE_ADDR"]) << "</p>"
96 "<p>Request URI: ("
97 << req.env().getRequestPath().size() << " elements): "
98 << req.env()["REQUEST_URI"] << "</p>"
99 "<p>HTTPS status: "
100 << req.env()["HTTPS"] << "</p>"
101 "<p>SERVER_NAME: "
102 << req.env()["SERVER_NAME"]
103 << "</p>"
104 "<p>Server software: "
105 << req.env()["SERVER_SOFTWARE"] << "</p>"
106 "<p>Base URL: "
107 << req.env()["BASE_URL"] << "</p>"
108 "<p>Full URL with QS: "
109 << req.env()["FULL_URL_WITH_QS"] << "</p>"
110 "<p>Full URL without QS: "
111 << req.env()["FULL_URL_WITHOUT_QS"] << "</p>";
112
113 // test privileges
114 auto currentUid = getuid();
115 auto currentGid = getgid();
116 auto currentEUid = geteuid();
117 auto currentEGid = getegid();
118 int groupCount = getgroups(0, nullptr);
119 resp << "<p>Privileges: uid = " << currentUid << "; gid = " << currentGid << "; euid = "
120 << currentEUid << "; egid = " << currentEGid << "</p>";
121 vector<gid_t> currentGL(groupCount, 0);
122 if (getgroups(groupCount, &currentGL[0]) >= 0) {
123 resp << "<p>Current groups: ";
124 for (auto const& e : currentGL) {
125 resp << e << ", ";
126 }
127 resp << "</p>";
128 }
129
130 // alternative: session["test"].isSet()
131 if (session.isSet("test")) {
132 resp << "<p>Session available! Value: " << any_cast<string>(session["test"])
133 << "</p>";
134 session.invalidate();
135 session.start();
136 session.set("test", string("and even more blah"));
137
138 } else {
139 session.set("test", "blah blah blah");
140 resp << "<p>There was no session yet, but now there should be one!"
141 << "</p>";
142 }
143
144 string encodedDecoded = encoding::htmlDecode(encoded);
145 if (decoded == encodedDecoded) {
146 resp << "<p>yay!</p>";
147 } else {
148 resp << "<p>" << encoding::htmlEncode(encodedDecoded) << "</p>";
149 }
150
151 connection.flushResponse();
152
153 resp << "<p>Hello World 2!</p>"
154 "</body></html>";
155
156 return 0;
157}
Class for managing sessions and getting and setting connection-independent session data.
This file will be configured by CMake and contains the necessary properties to ensure that a loaded a...
std::vector< BlockFilter > & blockFilters() noexcept
bool & filtersEnabled() noexcept
std::vector< AuthFilter > & authFilters() noexcept
std::vector< ForwardFilter > & forwardFilters() noexcept
std::vector< std::string > & extensionFilter() noexcept
std::regex & regexFilter() noexcept
bool & invert() noexcept
bool & regexFilterEnabled() noexcept
std::vector< std::vector< std::string > > & pathFilter() noexcept
bool & invertExtensionFilter() noexcept
AccessFilterList & accessFilters()
Definition: AppInit.cpp:47
std::string & authName() noexcept
std::function< bool(std::string, std::string)> & authFunction() noexcept
unsigned int & status() noexcept
nawa::Session & session() noexcept
Definition: Connection.cpp:361
void setCookiePolicy(Cookie policy)
Definition: Connection.cpp:349
void setCookie(std::string const &key, Cookie cookie)
Definition: Connection.cpp:314
std::ostream & responseStream() noexcept
Definition: Connection.cpp:377
nawa::Request const & request() const noexcept
Definition: Connection.cpp:357
std::string & basePath() noexcept
std::string start(std::string sessionId, std::optional< unsigned long > keepalive=std::nullopt)
Definition: Session.cpp:127
Namespace containing functions for text encoding and decoding.
std::string htmlEncode(std::string input, bool encodeAll=false)
Definition: encoding.cpp:133
std::string htmlDecode(std::string input)
Definition: encoding.cpp:185
Definition: AppInit.h:31
int handleRequest(Connection &connection)
Definition: nawatest.cpp:75
int init(nawa::AppInit &appInit)
Definition: nawatest.cpp:33