7a04f298d2
- update to latest telegram layer - remove some references to fields in tg.Entities that don't exist in the schema - originally added here: https://github.com/beeper/td/commit/820929062a2ba0104397bc01235ab58a9cff780e - referenced here - https://github.com/mautrix/telegramgo/commit/124f0967ed195b5a380c9bd02e170ada9710dde3 - https://github.com/mautrix/telegramgo/commit/4205047aab2e0639217148b5d125bfaab668bd8e
90 lines
1.8 KiB
Go
90 lines
1.8 KiB
Go
package html
|
|
|
|
import (
|
|
"net"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
"unicode/utf8"
|
|
|
|
"github.com/go-faster/errors"
|
|
|
|
"go.mau.fi/mautrix-telegram/pkg/gotd/ascii"
|
|
"go.mau.fi/mautrix-telegram/pkg/gotd/telegram/message/entity"
|
|
)
|
|
|
|
func isIPv6(str string) bool {
|
|
ip := net.ParseIP(str)
|
|
return strings.Contains(str, ":") && ip != nil
|
|
}
|
|
|
|
func validateHostname(u *url.URL) error {
|
|
// TODO(tdakkota): make sure that it is correct
|
|
ipv6 := isIPv6(u.Host)
|
|
if !strings.ContainsRune(u.Host, '.') && ipv6 {
|
|
return errors.New("wrong HTTP URL")
|
|
}
|
|
if ipv6 {
|
|
return nil
|
|
}
|
|
|
|
allowedSymbol := func(c rune) bool {
|
|
return ascii.IsLatinLetter(c) ||
|
|
ascii.IsDigit(c) ||
|
|
(c >= '&' && c <= '.') ||
|
|
c == '_' ||
|
|
c == '!' ||
|
|
c == '$' ||
|
|
c == '~' ||
|
|
c == ';' ||
|
|
c == '=' ||
|
|
c > utf8.RuneSelf
|
|
}
|
|
|
|
for _, c := range u.Host {
|
|
if !allowedSymbol(c) {
|
|
return errors.Errorf("disallowed character %c in URL host", c)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func getURLFormatter(rawURL string, resolver entity.UserResolver) (entity.Formatter, error) {
|
|
const defaultProtocol = "http"
|
|
if rawURL == "" {
|
|
return nil, errors.New("empty URL")
|
|
}
|
|
|
|
// FIXME(tdakkota): move normalization to deeplink package when it's done?
|
|
u, err := url.Parse(rawURL)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if u.Scheme == "tg" && u.Host == "user" {
|
|
id, err := strconv.ParseInt(u.Query().Get("id"), 10, 64)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "invalid user ID %q", id)
|
|
}
|
|
|
|
user, err := resolver(id)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "can't resolve user %q", id)
|
|
}
|
|
|
|
return entity.MentionName(user), nil
|
|
}
|
|
if u.Scheme == "" {
|
|
u.Scheme = defaultProtocol
|
|
u.Host = u.Path
|
|
u.Path = "/"
|
|
rawURL = u.String()
|
|
}
|
|
|
|
if err := validateHostname(u); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return entity.TextURL(rawURL), nil
|
|
}
|