WebFramework v3.0.12
Web framework for C++.
Loading...
Searching...
No Matches
ResourceExecutor.cpp
1#include "ResourceExecutor.h"
2
3#include <fstream>
4
5#include "Import/WebFramework.h"
6#include "Import/WebFrameworkConstants.h"
7#include "Exceptions/FileDoesNotExistException.h"
8#include "Exceptions/BadRequestException.h"
9
10using namespace std;
11
12namespace framework
13{
14 void ResourceExecutor::loadHTMLErrorsData()
15 {
16 filesystem::path allErrorsFolder(defaultAssets / web_framework_assets::errorsFolder);
17 ifstream html(allErrorsFolder / web_framework_assets::badRequest);
18 auto readFile = [](ifstream& html) -> string
19 {
20 string result;
21 string tem;
22
23 while (getline(html, tem))
24 {
25 result += tem + '\n';
26 }
27
28 html.close();
29
30 return result;
31 };
32
33 HTMLErrorsData[HTMLErrors::badRequest400] = readFile(html);
34
35 html.open(allErrorsFolder / web_framework_assets::notFound);
36
37 HTMLErrorsData[HTMLErrors::notFound404] = readFile(html);
38
39 html.open(allErrorsFolder / web_framework_assets::internalServerError);
40
41 HTMLErrorsData[HTMLErrors::internalServerError500] = readFile(html);
42 }
43
44 void ResourceExecutor::readFile(string& result, unique_ptr<file_manager::ReadFileHandle>&& handle)
45 {
46 result = handle->readAllData();
47
48 if (result.empty())
49 {
50 throw exceptions::BadRequestException("File is empty");
51 }
52 }
53
54 ResourceExecutor::ResourceExecutor(const json::JSONParser& configuration, const filesystem::path& assets, uint64_t cachingSize, const filesystem::path& pathToTemplates) :
55 defaultAssets
56 (
57 configuration.getObject(json_settings::webFrameworkObject).contains(json_settings::webFrameworkDefaultAssetsPath, json::utility::variantTypeEnum::jString) ?
58 configuration.getObject(json_settings::webFrameworkObject).getString(json_settings::webFrameworkDefaultAssetsPath) :
59 webFrameworkDefaultAssests
60 ),
61 assets(assets),
62 dynamicPages(pathToTemplates),
63 fileManager(file_manager::FileManager::getInstance())
64 {
65 fileManager.getCache().setCacheSize(cachingSize);
66 }
67
68 void ResourceExecutor::init(const utility::JSONSettingsParser::ExecutorSettings& settings)
69 {
70 if (!filesystem::exists(assets))
71 {
72 filesystem::create_directories(assets);
73 }
74
75 if (!filesystem::exists(dynamicPages.getPathToTemplates()))
76 {
77 filesystem::create_directories(dynamicPages.getPathToTemplates());
78 }
79
80 this->loadHTMLErrorsData();
81 }
82
83 void ResourceExecutor::sendStaticFile(const string& filePath, HTTPResponse& response, bool isBinary, const string& fileName)
84 {
85 string result;
86 filesystem::path assetFilePath(assets / filePath);
87
88 if (!filesystem::exists(assetFilePath))
89 {
90 throw file_manager::exceptions::FileDoesNotExistException(assetFilePath);
91 }
92
93 if (isBinary)
94 {
95 fileManager.readBinaryFile(assetFilePath, bind(&ResourceExecutor::readFile, this, ref(result), placeholders::_1));
96 }
97 else
98 {
99 fileManager.readFile(assetFilePath, bind(&ResourceExecutor::readFile, this, ref(result), placeholders::_1));
100 }
101
102 if (fileName.size())
103 {
104 response.addHeader("Content-Disposition", format(R"(attachment; filename="{}")", fileName));
105 }
106
107 response.addBody(move(result));
108 }
109
110 void ResourceExecutor::sendDynamicFile(const string& filePath, HTTPResponse& response, const unordered_map<string, string>& variables, bool isBinary, const string& fileName)
111 {
112 string result;
113 filesystem::path assetFilePath(assets / filePath);
114
115 if (!filesystem::exists(assetFilePath))
116 {
117 throw file_manager::exceptions::FileDoesNotExistException(assetFilePath);
118 }
119
120 if (isBinary)
121 {
122 fileManager.readBinaryFile(assetFilePath, bind(&ResourceExecutor::readFile, this, ref(result), placeholders::_1));
123 }
124 else
125 {
126 fileManager.readFile(assetFilePath, bind(&ResourceExecutor::readFile, this, ref(result), placeholders::_1));
127 }
128
129 dynamicPages.run(variables, result);
130
131 if (fileName.size())
132 {
133 response.addHeader("Content-Disposition", format(R"(attachment; filename="{}")", fileName));
134 }
135
136 response.addBody(move(result));
137 }
138
139 void ResourceExecutor::registerDynamicFunction(const string& functionName, function<string(const vector<string>&)>&& function)
140 {
141 dynamicPages.registerDynamicFunction(functionName, move(function));
142 }
143
144 void ResourceExecutor::unregisterDynamicFunction(const string& functionName)
145 {
146 dynamicPages.unregisterDynamicFunction(functionName);
147 }
148
149 bool ResourceExecutor::isDynamicFunctionRegistered(const string& functionName)
150 {
151 return dynamicPages.isDynamicFunctionRegistered(functionName);
152 }
153
154 void ResourceExecutor::doGet(HTTPRequest& request, HTTPResponse& response)
155 {
156 request.sendAssetFile(request.getRawParameters(), response);
157 }
158
159 void ResourceExecutor::doPost(HTTPRequest& request, HTTPResponse& response) //-V524
160 {
161 request.sendAssetFile(request.getRawParameters(), response);
162 }
163
164 const filesystem::path& ResourceExecutor::getPathToAssets() const
165 {
166 return assets;
167 }
168
169 void ResourceExecutor::notFoundError(HTTPResponse& response, const exception* exception)
170 {
171 const string& message = HTMLErrorsData[HTMLErrors::notFound404];
172
173#ifdef NDEBUG
174 response.addBody(message);
175#else
176 if (exception)
177 {
178 response.addBody(format("{} Exception: {}", message, exception->what()));
179 }
180 else
181 {
182 response.addBody(message);
183 }
184#endif
185
186 response.setResponseCode(web::responseCodes::notFound);
187 }
188
189 void ResourceExecutor::badRequestError(HTTPResponse& response, const exception* exception)
190 {
191 const string& message = HTMLErrorsData[HTMLErrors::badRequest400];
192
193#ifdef NDEBUG
194 response.addBody(message);
195#else
196 if (exception)
197 {
198 response.addBody(format("{} Exception: {}", message, exception->what()));
199 }
200 else
201 {
202 response.addBody(message);
203 }
204#endif
205
206 response.setResponseCode(web::responseCodes::badRequest);
207 }
208
209 void ResourceExecutor::internalServerError(HTTPResponse& response, const exception* exception)
210 {
211 const string& message = HTMLErrorsData[HTMLErrors::internalServerError500];
212
213#ifdef NDEBUG
214 response.addBody(message);
215#else
216 if (exception)
217 {
218 response.addBody(format("{} Exception: {}", message, exception->what()));
219 }
220 else
221 {
222 response.addBody(message);
223 }
224#endif
225
226 response.setResponseCode(web::responseCodes::internalServerError);
227 }
228
229 bool ResourceExecutor::getIsCaching() const
230 {
231 return fileManager.getCache().getCacheSize();
232 }
233}
Parsing HTTP request.
Definition HTTPRequest.h:25
const std::string & getRawParameters() const
Parameters string from HTTP.
void sendAssetFile(const std::string &filePath, HTTPResponse &response, const std::unordered_map< std::string, std::string > &variables={}, bool isBinary=true, const std::string &fileName="")
ResourceExecutor wrapper.
HTTPBuilder wrapper.
void addBody(const std::string &body)
void addHeader(const std::string &name, const std::string &value)
Set additional HTTP header.
void setResponseCode(web::responseCodes code)
Set HTTP response code.