NAWA  0.8
Web Application Framework for C++
nawatest.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 <iostream>
25 #include <nawa/application.h>
26 #include <nawa/session/Session.h>
27 #include <nawa/util/encoding.h>
28 #include <unistd.h>
29 
30 using namespace nawa;
31 using namespace std;
32 
33 int 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 
75 int 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.
std::vector< ForwardFilter > & forwardFilters() noexcept
std::vector< AuthFilter > & authFilters() noexcept
bool & filtersEnabled() noexcept
std::vector< BlockFilter > & blockFilters() noexcept
bool & invert() noexcept
bool & regexFilterEnabled() noexcept
std::vector< std::string > & extensionFilter() noexcept
std::regex & regexFilter() noexcept
bool & invertExtensionFilter() noexcept
std::vector< std::vector< std::string > > & pathFilter() noexcept
AccessFilterList & accessFilters()
Definition: AppInit.cpp:47
std::function< bool(std::string, std::string)> & authFunction() noexcept
std::string & authName() 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
void start(nawa::Cookie properties=Cookie())
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