ferencd@0: #include "web_component.h" ferencd@0: #include "flood_check.h" ferencd@0: #include "log.h" ferencd@0: #include "fake_locations.h" ferencd@0: #include "dictionary.h" ferencd@0: ferencd@0: #include ferencd@0: #include ferencd@0: #include ferencd@0: #include ferencd@0: #include ferencd@0: ferencd@0: tnt::MimeDb web_component::mimeDb = tnt::MimeDb("/etc/mime.types"); ferencd@0: ferencd@0: const std::string web_component::WEB_NOT_FOUND = "/static/404.html"; ferencd@0: struct SleepRecommendation ferencd@0: { ferencd@0: int attempt = 0; ferencd@0: int sleep_time = 0; ferencd@0: }; ferencd@0: ferencd@0: static std::map sleep_times; ferencd@0: ferencd@0: web_component::web_component(tnt::HttpRequest &request, tnt::HttpReply &reply, const std::string &sessionId) ferencd@0: : mrequest(request), mreply(reply), m_sessionId(sessionId) ferencd@0: { ferencd@0: // see that this IP is not trying to flood our system ferencd@0: m_originatingIp = ""; ferencd@0: ferencd@0: std::string originatingIp = request.getHeader("X-Forwarded-For:"); ferencd@0: info() << "got originating IP: " << originatingIp; ferencd@0: ferencd@0: /*auto hit = request.header_begin(); ferencd@0: debug() << "Full header:"; ferencd@0: while(hit != request.header_end()) ferencd@0: { ferencd@0: if(boost::starts_with(hit->first, "X-Forwarded-For")) ferencd@0: { ferencd@0: originatingIp = hit->first; ferencd@0: m_originatingIp = originatingIp; ferencd@0: ferencd@0: } ferencd@0: debug() << hit->first << " -- " << hit->second; ferencd@0: hit ++; ferencd@0: }*/ ferencd@0: ferencd@0: if(originatingIp.empty()) ferencd@0: { ferencd@0: originatingIp = request.getPeerIp(); ferencd@0: } ferencd@0: ferencd@0: m_originatingIp = originatingIp; ferencd@0: ferencd@0: // firstly see the fake URLs ferencd@0: std::string requestedUri = request.getPathInfo(); ferencd@0: if(std::find(fake_locations.begin(), fake_locations.end(), requestedUri) != fake_locations.end() || requestedUri.find(".php") != std::string::npos) ferencd@0: { ferencd@0: if(sleep_times.count(m_originatingIp) == 0) ferencd@0: { ferencd@0: sleep_times[m_originatingIp] = {1, 0}; ferencd@0: } ferencd@0: else ferencd@0: { ferencd@0: sleep_times[m_originatingIp].attempt ++; ferencd@0: } ferencd@0: ferencd@0: // with every 50 fake request attempts increase the sleep time with 1 second ferencd@0: if(sleep_times[m_originatingIp].attempt > 50) ferencd@0: { ferencd@0: sleep_times[m_originatingIp].sleep_time ++; ferencd@0: sleep_times[m_originatingIp].attempt = 0; ferencd@0: } ferencd@0: ferencd@0: if(sleep_times[m_originatingIp].sleep_time > 0) ferencd@0: { ferencd@0: std::this_thread::sleep_for(std::chrono::seconds(sleep_times[m_originatingIp].sleep_time)); ferencd@0: } ferencd@0: ferencd@0: throw "fake"; ferencd@0: } ferencd@0: ferencd@0: // this will throw if sees a flooding attempt ferencd@0: flood_check::attempt(originatingIp); ferencd@0: ferencd@0: } ferencd@0: ferencd@0: size_t replace(std::string& str, const std::string& from, const std::string& to, size_t pos) ferencd@0: { ferencd@0: size_t start_pos = str.find(from, pos); ferencd@0: if(start_pos == std::string::npos) ferencd@0: return std::string::npos; ferencd@0: str.replace(start_pos, from.length(), to); ferencd@0: return start_pos + to.length(); ferencd@0: } ferencd@0: ferencd@0: std::string web_component::prepareLangJs(const std::map > &translations) ferencd@0: { ferencd@0: std::map> languageToSpanIdTranslations; ferencd@0: ferencd@0: for(const auto& [spanId, languageMap] : translations) ferencd@0: { ferencd@0: for(const auto& [langId, translated] : languageMap) ferencd@0: { ferencd@0: languageToSpanIdTranslations[langId][spanId] = translated; ferencd@0: } ferencd@0: } ferencd@0: ferencd@0: std::string javascript = "function changeTexts(l) {"; ferencd@0: ferencd@0: for(const auto& [lang, langMap] : languageToSpanIdTranslations) ferencd@0: { ferencd@0: javascript += std::string("if(l == '") + lang + "') {"; ferencd@0: for(const auto& [spanId, translated] : langMap) ferencd@0: { ferencd@0: std::string translated_c = translated; ferencd@0: size_t pos = 0; ferencd@0: while(pos != std::string::npos) pos = replace(translated_c, "'", "\\'", pos); ferencd@0: javascript += "$('#" + spanId + "').html('" + translated_c + "');\n"; ferencd@0: } ferencd@0: javascript += "}"; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: javascript += "}\n"; ferencd@0: ferencd@0: return javascript; ferencd@0: } ferencd@0: ferencd@0: void web_component::prepareLanguages() ferencd@0: { ferencd@0: // populate the supported languages ferencd@0: for(const auto& supportedLang : dictionary::supported_languages) ferencd@0: { ferencd@0: template_struct language("supported_language", "supported_language_item"); ferencd@0: language["code"] = supportedLang; ferencd@0: m_languageStructs.push_back(language); ferencd@0: } ferencd@0: ferencd@0: }