Support tonsite protocol.

This commit is contained in:
levlam 2024-07-17 08:36:56 +03:00
parent 5991a78334
commit d26e0fab57
4 changed files with 28 additions and 11 deletions

View File

@ -1056,21 +1056,25 @@ string LinkManager::get_checked_link(Slice link, bool http_only, bool https_only
Result<string> LinkManager::check_link_impl(Slice link, bool http_only, bool https_only) { Result<string> LinkManager::check_link_impl(Slice link, bool http_only, bool https_only) {
bool is_tg = false; bool is_tg = false;
bool is_ton = false; bool is_ton = false;
bool is_tonsite = false;
if (tolower_begins_with(link, "tg:")) { if (tolower_begins_with(link, "tg:")) {
link.remove_prefix(3); link.remove_prefix(3);
is_tg = true; is_tg = true;
} else if (tolower_begins_with(link, "ton:")) { } else if (tolower_begins_with(link, "ton:")) {
link.remove_prefix(4); link.remove_prefix(4);
is_ton = true; is_ton = true;
} else if (tolower_begins_with(link, "tonsite:")) {
link.remove_prefix(8);
is_tonsite = true;
} }
if ((is_tg || is_ton) && begins_with(link, "//")) { if ((is_tg || is_ton || is_tonsite) && begins_with(link, "//")) {
link.remove_prefix(2); link.remove_prefix(2);
} }
TRY_RESULT(http_url, parse_url(link)); TRY_RESULT(http_url, parse_url(link));
if (https_only && (http_url.protocol_ != HttpUrl::Protocol::Https || is_tg || is_ton)) { if (https_only && (http_url.protocol_ != HttpUrl::Protocol::Https || is_tg || is_ton || is_tonsite)) {
return Status::Error("Only HTTPS links are allowed"); return Status::Error("Only HTTPS links are allowed");
} }
if (is_tg || is_ton) { if (is_tg || is_ton || is_tonsite) {
if (http_only) { if (http_only) {
return Status::Error("Only HTTP links are allowed"); return Status::Error("Only HTTP links are allowed");
} }
@ -1089,7 +1093,7 @@ Result<string> LinkManager::check_link_impl(Slice link, bool http_only, bool htt
return Status::Error("Unallowed characters in URL host"); return Status::Error("Unallowed characters in URL host");
} }
} }
return PSTRING() << (is_tg ? "tg" : "ton") << "://" << http_url.host_ << query; return PSTRING() << (is_tg ? "tg" : (is_tonsite ? "tonsite" : "ton")) << "://" << http_url.host_ << query;
} }
if (http_url.host_.find('.') == string::npos && !http_url.is_ipv6_) { if (http_url.host_.find('.') == string::npos && !http_url.is_ipv6_) {

View File

@ -632,7 +632,7 @@ static vector<Slice> match_tg_urls(Slice str) {
const unsigned char *end = str.uend(); const unsigned char *end = str.uend();
const unsigned char *ptr = begin; const unsigned char *ptr = begin;
// '(tg|ton)://[a-z0-9_-]{1,253}([/?#][^\s\x{2000}-\x{200b}\x{200e}-\x{200f}\x{2016}-\x{206f}<>«»"]*)?' // '(tg|ton|tonsite)://[a-z0-9_-]{1,253}([/?#][^\s\x{2000}-\x{200b}\x{200e}-\x{200f}\x{2016}-\x{206f}<>«»"]*)?'
Slice bad_path_end_chars(".:;,('?!`"); Slice bad_path_end_chars(".:;,('?!`");
@ -648,6 +648,10 @@ static vector<Slice> match_tg_urls(Slice str) {
url_begin = ptr - 2; url_begin = ptr - 2;
} else if (ptr - begin >= 3 && to_lower(ptr[-3]) == 't' && to_lower(ptr[-2]) == 'o' && to_lower(ptr[-1]) == 'n') { } else if (ptr - begin >= 3 && to_lower(ptr[-3]) == 't' && to_lower(ptr[-2]) == 'o' && to_lower(ptr[-1]) == 'n') {
url_begin = ptr - 3; url_begin = ptr - 3;
} else if (ptr - begin >= 7 && to_lower(ptr[-7]) == 't' && to_lower(ptr[-6]) == 'o' && to_lower(ptr[-5]) == 'n' &&
to_lower(ptr[-5]) == 's' && to_lower(ptr[-5]) == 'i' && to_lower(ptr[-5]) == 't' &&
to_lower(ptr[-5]) == 'e') {
url_begin = ptr - 3;
} }
} }
if (url_begin == nullptr) { if (url_begin == nullptr) {
@ -867,6 +871,8 @@ static vector<Slice> match_urls(Slice str) {
url_begin_ptr = url_begin_ptr - 8; url_begin_ptr = url_begin_ptr - 8;
} else if (ends_with(protocol, "ftp") && protocol != "tftp" && protocol != "sftp") { } else if (ends_with(protocol, "ftp") && protocol != "tftp" && protocol != "sftp") {
url_begin_ptr = url_begin_ptr - 6; url_begin_ptr = url_begin_ptr - 6;
} else if (ends_with(protocol, "tonsite")) {
url_begin_ptr = url_begin_ptr - 10;
} else { } else {
is_bad = true; is_bad = true;
} }
@ -1166,8 +1172,9 @@ static Slice fix_url(Slice str) {
auto full_url = str; auto full_url = str;
bool has_protocol = false; bool has_protocol = false;
auto str_begin = to_lower(str.substr(0, 8)); auto str_begin = to_lower(str.substr(0, 10));
if (begins_with(str_begin, "http://") || begins_with(str_begin, "https://") || begins_with(str_begin, "ftp://")) { if (begins_with(str_begin, "http://") || begins_with(str_begin, "https://") || begins_with(str_begin, "ftp://") ||
begins_with(str_begin, "tonsite://")) {
auto pos = str.find(':'); auto pos = str.find(':');
str = str.substr(pos + 3); str = str.substr(pos + 3);
has_protocol = true; has_protocol = true;
@ -1788,8 +1795,9 @@ Slice get_first_url(const FormattedText &text) {
continue; continue;
} }
auto url = utf8_utf16_substr(text.text, entity.offset, entity.length); auto url = utf8_utf16_substr(text.text, entity.offset, entity.length);
string scheme = to_lower(url.substr(0, 4)); string scheme = to_lower(url.substr(0, 8));
if (scheme == "ton:" || begins_with(scheme, "tg:") || scheme == "ftp:" || is_plain_domain(url)) { if (scheme == "ton:" || begins_with(scheme, "tg:") || scheme == "ftp:" || scheme == "tonsite:" ||
is_plain_domain(url)) {
continue; continue;
} }
return url; return url;
@ -1814,8 +1822,8 @@ Slice get_first_url(const FormattedText &text) {
break; break;
case MessageEntity::Type::TextUrl: { case MessageEntity::Type::TextUrl: {
Slice url = entity.argument; Slice url = entity.argument;
string scheme = to_lower(url.substr(0, 4)); string scheme = to_lower(url.substr(0, 8));
if (scheme == "ton:" || begins_with(scheme, "tg:") || scheme == "ftp:") { if (scheme == "ton:" || begins_with(scheme, "tg:") || scheme == "ftp:" || scheme == "tonsite:") {
continue; continue;
} }
return url; return url;

View File

@ -79,6 +79,7 @@ TEST(Link, check_link) {
check_link("http://..", "http://../"); check_link("http://..", "http://../");
check_link("..", "http://../"); check_link("..", "http://../");
check_link("https://.", ""); check_link("https://.", "");
check_link("tOnSiTe://google", "tonsite://google/");
} }
static td::td_api::object_ptr<td::td_api::InternalLinkType> get_internal_link_type_object( static td::td_api::object_ptr<td::td_api::InternalLinkType> get_internal_link_type_object(

View File

@ -501,6 +501,10 @@ TEST(MessageEntities, url) {
check_url("ftp://telegram.org", {"ftp://telegram.org"}); check_url("ftp://telegram.org", {"ftp://telegram.org"});
check_url("ftps://telegram.org", {}); check_url("ftps://telegram.org", {});
check_url("sftp://telegram.org", {}); check_url("sftp://telegram.org", {});
check_url("tonsite://telegram.ton", {"tonsite://telegram.ton"});
check_url("telegram.ton", {"telegram.ton"});
check_url("telegram.onion", {"telegram.onion"});
check_url("telegram.tonsite", {});
check_url("hTtPs://telegram.org", {"hTtPs://telegram.org"}); check_url("hTtPs://telegram.org", {"hTtPs://telegram.org"});
check_url("HTTP://telegram.org", {"HTTP://telegram.org"}); check_url("HTTP://telegram.org", {"HTTP://telegram.org"});
check_url("аHTTP://telegram.org", {"HTTP://telegram.org"}); check_url("аHTTP://telegram.org", {"HTTP://telegram.org"});