107 line
3.3 KiB
C++
107 line
3.3 KiB
C++
/* Copyright (c) 2018 Albert S.
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
*/
|
|
#include "httpgateway.h"
|
|
#include "../logger.h"
|
|
HttpGateway::HttpGateway(const Config &config)
|
|
{
|
|
this->listenaddr = config.getConfig("http.listenaddr");
|
|
if(this->listenaddr.empty())
|
|
{
|
|
throw new std::runtime_error("No http.listenaddr in config file");
|
|
}
|
|
std::string listenport = config.getConfig("http.listenport");
|
|
if(listenport.empty())
|
|
{
|
|
throw new std::runtime_error("No http.listenport in config file");
|
|
}
|
|
this->listenport = std::stoi(listenport);
|
|
|
|
this->maxPayloadLength = config.max_payload_length;
|
|
}
|
|
|
|
bool HttpGateway::keepReading()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
Request HttpGateway::convertRequest(httplib::Request request)
|
|
{
|
|
Request result;
|
|
result.setRequestMethod(request.method);
|
|
result.setUrl(request.target);
|
|
|
|
// TODO: this eats resources, where perhaps it does not need to. move it to request?
|
|
for(auto &it : request.params)
|
|
{
|
|
it.second = utils::html_xss(std::string{it.second});
|
|
}
|
|
if(request.method == "GET")
|
|
{
|
|
result.setGetVars(request.params);
|
|
}
|
|
else
|
|
{
|
|
result.initGetMap(request.target);
|
|
result.setPostVars(request.params);
|
|
}
|
|
|
|
if(request.has_header("COOKIE"))
|
|
{
|
|
result.initCookies(request.get_header_value("COOKIE"));
|
|
}
|
|
result.setIp(request.get_header_value("REMOTE_ADDR"));
|
|
|
|
return result;
|
|
}
|
|
|
|
httplib::Response HttpGateway::convertResponse(Response response)
|
|
{
|
|
httplib::Response result;
|
|
result.set_content(response.getBody(), response.getContentType().c_str());
|
|
result.status = response.getStatus();
|
|
for(auto &header : response.getResponseHeaders())
|
|
{
|
|
result.set_header(header.first.c_str(), header.second.c_str());
|
|
}
|
|
|
|
for(const Cookie &cookie : response.getCookies())
|
|
{
|
|
result.set_header("Set-Cookie", cookie.createHeaderValue().c_str());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void HttpGateway::work(RequestWorker &worker)
|
|
{
|
|
httplib::Server server;
|
|
server.set_payload_max_length(this->maxPayloadLength);
|
|
auto handler = [&](const httplib::Request &req, httplib::Response &res) {
|
|
Request wikiRequest = convertRequest(req);
|
|
Logger::debug() << "httpgateway: received request " << wikiRequest;
|
|
Response wikiresponse = worker.processRequest(wikiRequest);
|
|
|
|
res = convertResponse(wikiresponse);
|
|
};
|
|
server.Get("/(.*)", handler);
|
|
server.Post("/(.*)", handler);
|
|
server.listen(this->listenaddr.c_str(), this->listenport);
|
|
}
|