annotate server/web_component.cpp @ 0:a4671277546c tip

created the repository for the thymian project
author ferencd
date Tue, 17 Aug 2021 11:19:54 +0200
parents
children
rev   line source
ferencd@0 1 #include "web_component.h"
ferencd@0 2 #include "flood_check.h"
ferencd@0 3 #include "log.h"
ferencd@0 4 #include "fake_locations.h"
ferencd@0 5 #include "dictionary.h"
ferencd@0 6
ferencd@0 7 #include <boost/algorithm/string.hpp>
ferencd@0 8 #include <algorithm>
ferencd@0 9 #include <thread>
ferencd@0 10 #include <chrono>
ferencd@0 11 #include <map>
ferencd@0 12
ferencd@0 13 tnt::MimeDb web_component::mimeDb = tnt::MimeDb("/etc/mime.types");
ferencd@0 14
ferencd@0 15 const std::string web_component::WEB_NOT_FOUND = "/static/404.html";
ferencd@0 16 struct SleepRecommendation
ferencd@0 17 {
ferencd@0 18 int attempt = 0;
ferencd@0 19 int sleep_time = 0;
ferencd@0 20 };
ferencd@0 21
ferencd@0 22 static std::map<std::string, SleepRecommendation> sleep_times;
ferencd@0 23
ferencd@0 24 web_component::web_component(tnt::HttpRequest &request, tnt::HttpReply &reply, const std::string &sessionId)
ferencd@0 25 : mrequest(request), mreply(reply), m_sessionId(sessionId)
ferencd@0 26 {
ferencd@0 27 // see that this IP is not trying to flood our system
ferencd@0 28 m_originatingIp = "";
ferencd@0 29
ferencd@0 30 std::string originatingIp = request.getHeader("X-Forwarded-For:");
ferencd@0 31 info() << "got originating IP: " << originatingIp;
ferencd@0 32
ferencd@0 33 /*auto hit = request.header_begin();
ferencd@0 34 debug() << "Full header:";
ferencd@0 35 while(hit != request.header_end())
ferencd@0 36 {
ferencd@0 37 if(boost::starts_with(hit->first, "X-Forwarded-For"))
ferencd@0 38 {
ferencd@0 39 originatingIp = hit->first;
ferencd@0 40 m_originatingIp = originatingIp;
ferencd@0 41
ferencd@0 42 }
ferencd@0 43 debug() << hit->first << " -- " << hit->second;
ferencd@0 44 hit ++;
ferencd@0 45 }*/
ferencd@0 46
ferencd@0 47 if(originatingIp.empty())
ferencd@0 48 {
ferencd@0 49 originatingIp = request.getPeerIp();
ferencd@0 50 }
ferencd@0 51
ferencd@0 52 m_originatingIp = originatingIp;
ferencd@0 53
ferencd@0 54 // firstly see the fake URLs
ferencd@0 55 std::string requestedUri = request.getPathInfo();
ferencd@0 56 if(std::find(fake_locations.begin(), fake_locations.end(), requestedUri) != fake_locations.end() || requestedUri.find(".php") != std::string::npos)
ferencd@0 57 {
ferencd@0 58 if(sleep_times.count(m_originatingIp) == 0)
ferencd@0 59 {
ferencd@0 60 sleep_times[m_originatingIp] = {1, 0};
ferencd@0 61 }
ferencd@0 62 else
ferencd@0 63 {
ferencd@0 64 sleep_times[m_originatingIp].attempt ++;
ferencd@0 65 }
ferencd@0 66
ferencd@0 67 // with every 50 fake request attempts increase the sleep time with 1 second
ferencd@0 68 if(sleep_times[m_originatingIp].attempt > 50)
ferencd@0 69 {
ferencd@0 70 sleep_times[m_originatingIp].sleep_time ++;
ferencd@0 71 sleep_times[m_originatingIp].attempt = 0;
ferencd@0 72 }
ferencd@0 73
ferencd@0 74 if(sleep_times[m_originatingIp].sleep_time > 0)
ferencd@0 75 {
ferencd@0 76 std::this_thread::sleep_for(std::chrono::seconds(sleep_times[m_originatingIp].sleep_time));
ferencd@0 77 }
ferencd@0 78
ferencd@0 79 throw "fake";
ferencd@0 80 }
ferencd@0 81
ferencd@0 82 // this will throw if sees a flooding attempt
ferencd@0 83 flood_check::attempt(originatingIp);
ferencd@0 84
ferencd@0 85 }
ferencd@0 86
ferencd@0 87 size_t replace(std::string& str, const std::string& from, const std::string& to, size_t pos)
ferencd@0 88 {
ferencd@0 89 size_t start_pos = str.find(from, pos);
ferencd@0 90 if(start_pos == std::string::npos)
ferencd@0 91 return std::string::npos;
ferencd@0 92 str.replace(start_pos, from.length(), to);
ferencd@0 93 return start_pos + to.length();
ferencd@0 94 }
ferencd@0 95
ferencd@0 96 std::string web_component::prepareLangJs(const std::map<std::string, std::map<std::string, std::string> > &translations)
ferencd@0 97 {
ferencd@0 98 std::map<std::string, std::map<std::string, std::string>> languageToSpanIdTranslations;
ferencd@0 99
ferencd@0 100 for(const auto& [spanId, languageMap] : translations)
ferencd@0 101 {
ferencd@0 102 for(const auto& [langId, translated] : languageMap)
ferencd@0 103 {
ferencd@0 104 languageToSpanIdTranslations[langId][spanId] = translated;
ferencd@0 105 }
ferencd@0 106 }
ferencd@0 107
ferencd@0 108 std::string javascript = "function changeTexts(l) {";
ferencd@0 109
ferencd@0 110 for(const auto& [lang, langMap] : languageToSpanIdTranslations)
ferencd@0 111 {
ferencd@0 112 javascript += std::string("if(l == '") + lang + "') {";
ferencd@0 113 for(const auto& [spanId, translated] : langMap)
ferencd@0 114 {
ferencd@0 115 std::string translated_c = translated;
ferencd@0 116 size_t pos = 0;
ferencd@0 117 while(pos != std::string::npos) pos = replace(translated_c, "'", "\\'", pos);
ferencd@0 118 javascript += "$('#" + spanId + "').html('" + translated_c + "');\n";
ferencd@0 119 }
ferencd@0 120 javascript += "}";
ferencd@0 121 }
ferencd@0 122
ferencd@0 123
ferencd@0 124 javascript += "}\n";
ferencd@0 125
ferencd@0 126 return javascript;
ferencd@0 127 }
ferencd@0 128
ferencd@0 129 void web_component::prepareLanguages()
ferencd@0 130 {
ferencd@0 131 // populate the supported languages
ferencd@0 132 for(const auto& supportedLang : dictionary::supported_languages)
ferencd@0 133 {
ferencd@0 134 template_struct language("supported_language", "supported_language_item");
ferencd@0 135 language["code"] = supportedLang;
ferencd@0 136 m_languageStructs.push_back(language);
ferencd@0 137 }
ferencd@0 138
ferencd@0 139 }