From df66c2d2dcc55355c9812e6b8cf265a753cd4595 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 23 May 2021 06:06:04 +0300 Subject: [PATCH] [i18n] translate HTTP proxy Signed-off-by: R4SAS --- i18n/I18N.h | 16 ++------ i18n/I18N_langs.h | 34 ++++++++++++++++ i18n/russian.cpp | 43 +++++++++++++++++++-- libi2pd/HTTP.cpp | 2 + libi2pd/RouterContext.h | 6 +-- libi2pd_client/HTTPProxy.cpp | 75 +++++++++++++++++++----------------- 6 files changed, 120 insertions(+), 56 deletions(-) create mode 100644 i18n/I18N_langs.h diff --git a/i18n/I18N.h b/i18n/I18N.h index eddec514..cb3e5c1c 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -11,20 +11,11 @@ #include "RouterContext.h" + namespace i2p { namespace i18n { - namespace english { - std::string GetString (std::string arg); - std::string GetPlural (std::string arg, int n); - } - - namespace russian { - std::string GetString (std::string arg); - std::string GetPlural (std::string arg, int n); - } - - std::string translate (std::string arg) + inline std::string translate (std::string arg) { switch (i2p::context.GetLanguage ()) { @@ -49,7 +40,8 @@ namespace i18n { } // i2p template -std::string tr (TArgs&&... args) { +std::string tr (TArgs&&... args) +{ return i2p::i18n::translate(std::forward(args)...); } diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h new file mode 100644 index 00000000..24c683b4 --- /dev/null +++ b/i18n/I18N_langs.h @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2021, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#ifndef __I18N_LANGS_H__ +#define __I18N_LANGS_H__ + +namespace i2p { + +enum Lang { + eEnglish = 0, + eRussian +}; + +namespace i18n { + + namespace english { + std::string GetString (std::string arg); + std::string GetPlural (std::string arg, int n); + } + + namespace russian { + std::string GetString (std::string arg); + std::string GetPlural (std::string arg, int n); + } + +} // i18n +} // i2p + +#endif // __I18N_LANGS_H__ diff --git a/i18n/russian.cpp b/i18n/russian.cpp index 892ee203..feb6fc63 100644 --- a/i18n/russian.cpp +++ b/i18n/russian.cpp @@ -16,8 +16,44 @@ namespace russian { // language static std::map strings { - {"Enabled", "Включено"}, - {"Disabled", "Выключено"} + // HTTP Proxy + {"Proxy error", "Ошибка прокси"}, + {"Proxy info", "Информация прокси"}, + {"Proxy error: Host not found", "Ошибка прокси: Адрес не найден"}, + {"Remote host not found in router's addressbook", "Запрошенный адрес не найден в адресной книге роутера"}, + {"You may try to find this host on jump services below", "Вы можете попробовать найти адрес на джамп сервисах ниже"}, + {"Invalid request", "Некорректный запрос"}, + {"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"}, + {"addresshelper is not supported", "addresshelper не поддерживается"}, + {"Host", "Адрес"}, + {"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"}, + {"already in router's addressbook", "уже а адресной книге роутера"}, + {"Click", "Нажмите"}, + {"here", "здесь"}, + {"to proceed", "чтобы продолжить"}, + {"to update record", "чтобы обновить запись"}, + {"Addresshelper found", "Найден addresshelper"}, + {"invalid request uri", "некорректный URI запроса"}, + {"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"}, + {"Outproxy failure", "Ошибка внешнего прокси"}, + {"bad outproxy settings", "некорректные настройки внешнего прокси"}, + {"not inside I2P network, but outproxy is not enabled", "не в I2P сети, но внешний прокси не включен"}, + {"unknown outproxy url", "неизвестный URL внешнего прокси"}, + {"cannot resolve upstream proxy", "не удается определить внешний прокси"}, + {"hostname too long", "имя хоста слишком длинное"}, + {"cannot connect to upstream socks proxy", "не удается подключиться к вышестоящему SOCKS прокси"}, + {"Cannot negotiate with socks proxy", "Не удается договориться с вышестоящим SOCKS прокси"}, + {"CONNECT error", "Ошибка CONNECT запроса"}, + {"Failed to Connect", "Не удалось подключиться"}, + {"socks proxy error", "ошибка SOCKS прокси"}, + {"failed to send request to upstream", "не удалось отправить запрос вышестоящему прокси"}, + {"No Reply From socks proxy", "Нет ответа от SOCKS прокси сервера"}, + {"cannot connect", "не удалось подключиться"}, + {"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"}, + {"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"}, + {"Host is down", "Адрес недоступен"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Не удалось установить соединение к запрошенному адресу, возможно он не в сети. Попробуйте повторить запрос позже."}, + {"", ""}, }; static std::map> plurals @@ -25,7 +61,8 @@ namespace russian { // language {"days", {"день", "дня", "дней"}}, {"hours", {"час", "часа", "часов"}}, {"minutes", {"минута", "минуты", "минут"}}, - {"seconds", {"секунда", "секунды", "секунд"}} + {"seconds", {"секунда", "секунды", "секунд"}}, + {"", {"", ""}}, }; std::string GetString (std::string arg) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index da4299e9..6ad245f0 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -187,6 +187,8 @@ namespace http params.clear(); for (const auto& it : tokens) { + if (!it.length()) // empty + continue; std::size_t eq = it.find ('='); if (eq != std::string::npos) { auto e = std::pair(it.substr(0, eq), it.substr(eq + 1)); diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index dad3fdca..1cb77a74 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -18,6 +18,7 @@ #include "Identity.h" #include "RouterInfo.h" #include "Garlic.h" +#include "I18N_langs.h" namespace i2p { @@ -50,11 +51,6 @@ namespace garlic eRouterErrorSymmetricNAT = 3 }; - enum Lang { - eEnglish = 0, - eRussian - }; - class RouterContext: public i2p::garlic::GarlicDestination { private: diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 6b2b8df7..aff165b0 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -28,6 +28,7 @@ #include "I2PTunnel.h" #include "Config.h" #include "HTTP.h" +#include "I18N.h" namespace i2p { namespace proxy { @@ -71,8 +72,8 @@ namespace proxy { void SentHTTPFailed(const boost::system::error_code & ecode); void HandleStreamRequestComplete (std::shared_ptr stream); /* error helpers */ - void GenericProxyError(const char *title, const char *description); - void GenericProxyInfo(const char *title, const char *description); + void GenericProxyError(const std::string& title, const std::string& description); + void GenericProxyInfo(const std::string& title, const std::string& description); void HostNotFound(std::string & host); void SendProxyError(std::string & content); @@ -151,17 +152,17 @@ namespace proxy { Done(shared_from_this()); } - void HTTPReqHandler::GenericProxyError(const char *title, const char *description) { + void HTTPReqHandler::GenericProxyError(const std::string& title, const std::string& description) { std::stringstream ss; - ss << "

Proxy error: " << title << "

\r\n"; + ss << "

" << tr("Proxy error") << ": " << title << "

\r\n"; ss << "

" << description << "

\r\n"; std::string content = ss.str(); SendProxyError(content); } - void HTTPReqHandler::GenericProxyInfo(const char *title, const char *description) { + void HTTPReqHandler::GenericProxyInfo(const std::string& title, const std::string& description) { std::stringstream ss; - ss << "

Proxy info: " << title << "

\r\n"; + ss << "

" << tr("Proxy info") << ": " << title << "

\r\n"; ss << "

" << description << "

\r\n"; std::string content = ss.str(); SendProxyError(content); @@ -169,9 +170,9 @@ namespace proxy { void HTTPReqHandler::HostNotFound(std::string & host) { std::stringstream ss; - ss << "

Proxy error: Host not found

\r\n" - << "

Remote host not found in router's addressbook

\r\n" - << "

You may try to find this host on jump services below:

\r\n" + ss << "

" << tr("Proxy error: Host not found") << "

\r\n" + << "

" << tr("Remote host not found in router's addressbook") << "

\r\n" + << "

" << tr("You may try to find this host on jump services below") << ":

\r\n" << "
    \r\n"; for (const auto& js : jumpservices) { ss << "
  • " << js.first << "
  • \r\n"; @@ -216,7 +217,7 @@ namespace proxy { b64 = i2p::http::UrlDecode(value); // if we need update exists, request formed with update param if (params["update"] == "true") { len += std::strlen("&update=true"); confirm = true; } - url.query.replace(pos, len, ""); + url.query.replace(pos - 1, len + 1, ""); // +-1 for taking ? and & before parameter return true; } @@ -268,7 +269,7 @@ namespace proxy { if (m_req_len < 0) { LogPrint(eLogError, "HTTPProxy: unable to parse request"); - GenericProxyError("Invalid request", "Proxy unable to parse your request"); + GenericProxyError(tr("Invalid request"), tr("Proxy unable to parse your request")); return true; /* parse error */ } @@ -283,7 +284,7 @@ namespace proxy { if (!m_Addresshelper) { LogPrint(eLogWarning, "HTTPProxy: addresshelper request rejected"); - GenericProxyError("Invalid request", "addresshelper is not supported"); + GenericProxyError(tr("Invalid request"), tr("addresshelper is not supported")); return true; } if (!i2p::client::context.GetAddressBook ().FindAddress (m_RequestURL.host) || m_Confirm) @@ -292,17 +293,19 @@ namespace proxy { LogPrint (eLogInfo, "HTTPProxy: added address from addresshelper for ", m_RequestURL.host); std::string full_url = m_RequestURL.to_string(); std::stringstream ss; - ss << "Host " << m_RequestURL.host << " added to router's addressbook from helper. " - << "Click here to proceed."; - GenericProxyInfo("Addresshelper found", ss.str().c_str()); + ss << tr("Host") <<" " << m_RequestURL.host << " " << tr("added to router's addressbook from helper") << ". "; + ss << tr("Click") << " " << tr("here") << " " << tr("to proceed") << "."; + GenericProxyInfo(tr("Addresshelper found"), ss.str()); return true; /* request processed */ } else { + std::string full_url = m_RequestURL.to_string(); std::stringstream ss; - ss << "Host " << m_RequestURL.host << " already in router's addressbook. " - << "Click here to update record."; - GenericProxyInfo("Addresshelper found", ss.str().c_str()); + ss << tr("Host") << " " << m_RequestURL.host << " " << tr("already in router's addressbook") << ". "; + ss << tr("Click") << " " << tr("here") << " " << tr("to update record") << "."; + GenericProxyInfo(tr("Addresshelper found"), ss.str()); return true; /* request processed */ } } @@ -315,7 +318,7 @@ namespace proxy { auto pos = uri.find(":"); if(pos == std::string::npos || pos == uri.size() - 1) { - GenericProxyError("Invalid Request", "invalid request uri"); + GenericProxyError(tr("Invalid Request"), tr("invalid request uri")); return true; } else @@ -358,7 +361,7 @@ namespace proxy { else { /* relative url and missing 'Host' header */ - GenericProxyError("Invalid request", "Can't detect destination host from request"); + GenericProxyError(tr("Invalid request"), tr("Can't detect destination host from request")); return true; } } @@ -375,11 +378,11 @@ namespace proxy { if(m_ProxyURL.parse(m_OutproxyUrl)) ForwardToUpstreamProxy(); else - GenericProxyError("Outproxy failure", "bad outproxy settings"); + GenericProxyError(tr("Outproxy failure"), tr("bad outproxy settings")); } else { LogPrint (eLogWarning, "HTTPProxy: outproxy failure for ", dest_host, ": no outproxy enabled"); - std::string message = "Host " + dest_host + " not inside I2P network, but outproxy is not enabled"; - GenericProxyError("Outproxy failure", message.c_str()); + std::stringstream ss; ss << tr("Host") << " " << dest_host << " " << tr("not inside I2P network, but outproxy is not enabled"); + GenericProxyError(tr("Outproxy failure"), ss.str()); } return true; } @@ -467,13 +470,13 @@ namespace proxy { else { // unknown type, complain - GenericProxyError("unknown outproxy url", m_ProxyURL.to_string().c_str()); + GenericProxyError(tr("unknown outproxy url"), m_ProxyURL.to_string()); } } void HTTPReqHandler::HandleUpstreamProxyResolved(const boost::system::error_code & ec, boost::asio::ip::tcp::resolver::iterator it, ProxyResolvedHandler handler) { - if(ec) GenericProxyError("cannot resolve upstream proxy", ec.message().c_str()); + if(ec) GenericProxyError(tr("cannot resolve upstream proxy"), ec.message()); else handler(*it); } @@ -481,7 +484,7 @@ namespace proxy { { if(!ec) { if(m_RequestURL.host.size() > 255) { - GenericProxyError("hostname too long", m_RequestURL.host.c_str()); + GenericProxyError(tr("hostname too long"), m_RequestURL.host); return; } uint16_t port = m_RequestURL.port; @@ -508,13 +511,13 @@ namespace proxy { reqsize += host.size(); m_socks_buf[++reqsize] = 0; boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_socks_buf, reqsize), boost::asio::transfer_all(), std::bind(&HTTPReqHandler::HandleSocksProxySendHandshake, this, std::placeholders::_1, std::placeholders::_2)); - } else GenericProxyError("cannot connect to upstream socks proxy", ec.message().c_str()); + } else GenericProxyError(tr("cannot connect to upstream socks proxy"), ec.message()); } void HTTPReqHandler::HandleSocksProxySendHandshake(const boost::system::error_code & ec, std::size_t bytes_transferred) { LogPrint(eLogDebug, "HTTPProxy: upstream socks handshake sent"); - if(ec) GenericProxyError("Cannot negotiate with socks proxy", ec.message().c_str()); + if(ec) GenericProxyError(tr("Cannot negotiate with socks proxy"), ec.message()); else m_proxysock->async_read_some(boost::asio::buffer(m_socks_buf, 8), std::bind(&HTTPReqHandler::HandleSocksProxyReply, this, std::placeholders::_1, std::placeholders::_2)); } @@ -556,7 +559,7 @@ namespace proxy { } else { - GenericProxyError("CONNECT error", "Failed to Connect"); + GenericProxyError(tr("CONNECT error"), tr("Failed to Connect")); } } @@ -567,7 +570,7 @@ namespace proxy { m_send_buf = m_ClientResponse.to_string(); boost::asio::async_write(*m_sock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&] (const boost::system::error_code & ec, std::size_t transferred) { - if(ec) GenericProxyError("socks proxy error", ec.message().c_str()); + if(ec) GenericProxyError(tr("socks proxy error"), ec.message()); else HandoverToUpstreamProxy(); }); } else { @@ -575,7 +578,7 @@ namespace proxy { LogPrint(eLogDebug, "HTTPProxy: send ", m_send_buf.size(), " bytes"); boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&](const boost::system::error_code & ec, std::size_t transferred) { - if(ec) GenericProxyError("failed to send request to upstream", ec.message().c_str()); + if(ec) GenericProxyError(tr("failed to send request to upstream"), ec.message()); else HandoverToUpstreamProxy(); }); } @@ -593,18 +596,18 @@ namespace proxy { ss << "error code: "; ss << (int) m_socks_buf[1]; std::string msg = ss.str(); - GenericProxyError("Socks Proxy error", msg.c_str()); + GenericProxyError(tr("socks proxy error"), msg); } } - else GenericProxyError("No Reply From socks proxy", ec.message().c_str()); + else GenericProxyError(tr("No Reply From socks proxy"), ec.message()); } void HTTPReqHandler::HandleUpstreamHTTPProxyConnect(const boost::system::error_code & ec) { if(!ec) { LogPrint(eLogDebug, "HTTPProxy: connected to http upstream"); - GenericProxyError("cannot connect", "http out proxy not implemented"); - } else GenericProxyError("cannot connect to upstream http proxy", ec.message().c_str()); + GenericProxyError(tr("cannot connect"), tr("http out proxy not implemented")); + } else GenericProxyError(tr("cannot connect to upstream http proxy"), ec.message()); } /* will be called after some data received from client */ @@ -637,7 +640,7 @@ namespace proxy { { if (!stream) { LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info"); - GenericProxyError("Host is down", "Can't create connection to requested host, it may be down. Please try again later."); + GenericProxyError(tr("Host is down"), tr("Can't create connection to requested host, it may be down. Please try again later.")); return; } if (Kill())