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