1#include "HTTPRequest.h"
3#include "FileManager.h"
4#include "HTTPSNetwork.h"
6#include "Exceptions/FileDoesNotExistException.h"
12 bool HTTPRequest::isWebFrameworkDynamicPages(
const string& filePath)
14 size_t extension = filePath.find(
'.');
16 if (extension == string::npos)
21 return string_view(filePath.data() + extension) == webFrameworkDynamicPagesExtension;
24 web::HTTPParser HTTPRequest::sendRequestToAnotherServer(string_view ip, string_view port, string_view request, DWORD timeout,
bool useHTTPS)
26 streams::IOSocketStream stream
29 make_unique<web::HTTPSNetwork>(ip, port, timeout) :
30 make_unique<web::HTTPNetwork>(ip, port, timeout)
37 return web::HTTPParser(response);
40 HTTPRequest::HTTPRequest(SessionsManager& session,
const web::BaseTCPServer& serverReference, interfaces::IStaticFile& staticResources, interfaces::IDynamicFile& dynamicResources, sqlite::SQLiteManager& database, sockaddr clientAddr, streams::IOSocketStream& stream) :
42 serverReference(serverReference),
45 clientAddr(clientAddr),
46 staticResources(staticResources),
47 dynamicResources(dynamicResources)
52 const string& HTTPRequest::getRawParameters()
const
54 return parser.getParameters();
57 const string& HTTPRequest::getMethod()
const
59 return parser.getMethod();
62 const unordered_map<string, string>& HTTPRequest::getKeyValueParameters()
const
64 return parser.getKeyValueParameters();
67 string HTTPRequest::getHTTPVersion()
const
69 return "HTTP/" + to_string(parser.getHTTPVersion());
72 const web::HeadersMap& HTTPRequest::getHeaders()
const
74 return parser.getHeaders();
77 const string& HTTPRequest::getBody()
const
79 return parser.getBody();
82 void HTTPRequest::setAttribute(
const string& name,
const string& value)
84 session.setAttribute(this->getClientIpV4(), name, value);
87 string HTTPRequest::getAttribute(
const string& name)
89 return session.getAttribute(this->getClientIpV4(), name);
92 void HTTPRequest::deleteSession()
94 session.deleteSession(this->getClientIpV4());
97 void HTTPRequest::deleteAttribute(
const string& name)
99 session.deleteAttribute(this->getClientIpV4(), name);
102 web::HeadersMap HTTPRequest::getCookies()
const
104 web::HeadersMap result;
105 const web::HeadersMap& headers = parser.getHeaders();
107 if (
auto it = headers.find(
"Cookie"); it != headers.end())
109 const string& cookies = it->second;
114 size_t findKey = cookies.find(
'=', offset);
115 size_t findValue = cookies.find(
"; ", offset);
116 string::const_iterator startKey = cookies.begin() + offset;
117 string::const_iterator endKey = cookies.begin() + findKey;
118 string::const_iterator startValue = endKey + 1;
119 string::const_iterator endValue = findValue != string::npos ? (cookies.begin() + findValue) : (cookies.end());
121 result.try_emplace(
string(startKey, endKey),
string(startValue, endValue));
123 if (findValue == string::npos)
128 offset = findValue + 2;
135 void HTTPRequest::sendAssetFile(
const string& filePath,
HTTPResponse& response,
const unordered_map<string, string>& variables,
bool isBinary,
const string& fileName)
137 HTTPRequest::isWebFrameworkDynamicPages(filePath) ?
138 this->sendDynamicFile(filePath, response, variables, isBinary, fileName) :
139 this->sendStaticFile(filePath, response, isBinary, fileName);
142 void HTTPRequest::sendStaticFile(
const string& filePath,
HTTPResponse& response,
bool isBinary,
const string& fileName)
144 staticResources.sendStaticFile(filePath, response, isBinary, fileName);
147 void HTTPRequest::sendDynamicFile(
const string& filePath,
HTTPResponse& response,
const unordered_map<string, string>& variables,
bool isBinary,
const string& fileName)
149 dynamicResources.sendDynamicFile(filePath, response, variables, isBinary, fileName);
152 void HTTPRequest::streamFile(string_view filePath,
HTTPResponse& response, string_view fileName,
size_t chunkSize)
154 filesystem::path assetFilePath(staticResources.getPathToAssets() / filePath);
155 file_manager::Cache& cache = file_manager::FileManager::getInstance().getCache();
157 if (!filesystem::exists(assetFilePath))
159 throw file_manager::exceptions::FileDoesNotExistException(assetFilePath);
162 web::HTTPBuilder builder = web::HTTPBuilder().
165 "Date", HTTPResponse::getFullDate(),
166 "Server",
"WebFramework-Server",
167 "Content-Type",
"application/octet-stream",
168 "Content-Disposition", format(R
"(attachment; filename="{}")", fileName),
169 "Connection",
"keep-alive",
170 "Content-Length", filesystem::file_size(assetFilePath)
172 responseCode(web::responseCodes::ok);
174 response.setIsValid(
false);
177#pragma warning(disable: 26800)
178 if (cache.contains(assetFilePath))
180 const string& data = cache[assetFilePath];
184 "DownloadType",
"from-cache"
187 stream << builder.build(data);
192 ifstream fileStream(assetFilePath, ios_base::binary);
193 string chunk(chunkSize,
'\0');
195 streamsize dataSize = fileStream.read(chunk.data(), chunkSize).gcount();
197 if (dataSize != chunkSize)
199 chunk.resize(dataSize);
202 cache.appendCache(assetFilePath, chunk);
206 "DownloadType",
"from-file"
209 stream << builder.build() + chunk;
212 while (!fileStream.eof())
214 dataSize = fileStream.read(chunk.data(), chunkSize).gcount();
216 if (dataSize != chunkSize)
218 chunk.resize(dataSize);
221 cache.appendCache(assetFilePath, chunk);
227 void HTTPRequest::registerDynamicFunction(
const string& functionName, function<
string(
const vector<string>&)>&& function)
229 dynamicResources.registerDynamicFunction(functionName, move(function));
232 void HTTPRequest::unregisterDynamicFunction(
const string& functionName)
234 dynamicResources.unregisterDynamicFunction(functionName);
237 bool HTTPRequest::isDynamicFunctionRegistered(
const string& functionName)
239 return dynamicResources.isDynamicFunctionRegistered(functionName);
242 const json::JSONParser& HTTPRequest::getJSON()
const
244 return parser.getJSON();
247 const vector<string>& HTTPRequest::getChunks()
const
249 return parser.getChunks();
252 const web::HTTPParser& HTTPRequest::getParser()
const
257 string HTTPRequest::getClientIpV4()
const
259 return web::BaseTCPServer::getClientIpV4(clientAddr);
262 string HTTPRequest::getServerIpV4()
const
264 return serverReference.getServerIpV4();
267 uint16_t HTTPRequest::getClientPort()
const
269 return web::BaseTCPServer::getClientPortV4(clientAddr);
272 uint16_t HTTPRequest::getServerPort()
const
274 return serverReference.getServerPortV4();
278 WEB_FRAMEWORK_API
const string& HTTPRequest::getRouteParameter<string>(
const string& routeParameterName)
280 return get<string>(routeParameters.at(routeParameterName));
284 WEB_FRAMEWORK_API
const int64_t& HTTPRequest::getRouteParameter<int64_t>(
const string& routeParameterName)
286 return get<int64_t>(routeParameters.at(routeParameterName));
290 WEB_FRAMEWORK_API
const double& HTTPRequest::getRouteParameter<double>(
const string& routeParameterName)
292 return get<double>(routeParameters.at(routeParameterName));
295 streams::IOSocketStream& operator >> (streams::IOSocketStream& stream,
HTTPRequest& request)
301 if (stream.eof() || stream.bad())
306 request.parser.parse(data);
311 ostream& operator << (ostream& stream,
const HTTPRequest& request)
313 const web::HTTPParser& parser = request.parser;
314 const auto& headers = parser.getHeaders();
316 stream << parser.getMethod() <<
" " << parser.getParameters() <<
" " << parser.getHTTPVersion() << endl;
318 for (
const auto& [name, value] : headers)
320 stream << name <<
": " << value << endl;
323 stream << endl << parser.getBody();