package api import ( "errors" "net/url" "regexp" "strings" ) var ( youtubeIDRE = regexp.MustCompile(`^[A-Za-z0-9_-]{11}$`) rutubeIDRE = regexp.MustCompile(`^[a-f0-9]{32}$`) errVideoURL = errors.New("video url") ) // embedVideoURL приводит ссылку на видеоотзыв к адресу для встраивания. // Адрес попадает в src у iframe, поэтому пропускаем только YouTube и Rutube: // произвольная ссылка (например, javascript:) выполнилась бы на странице сайта. func embedVideoURL(raw string) (string, error) { raw = strings.TrimSpace(raw) if raw == "" { return "", nil } u, err := url.Parse(raw) if err != nil || (u.Scheme != "https" && u.Scheme != "http") { return "", errVideoURL } host := strings.TrimPrefix(strings.ToLower(u.Hostname()), "www.") host = strings.TrimPrefix(host, "m.") parts := strings.Split(strings.Trim(u.Path, "/"), "/") youtube := func(id string) (string, error) { if !youtubeIDRE.MatchString(id) { return "", errVideoURL } return "https://www.youtube.com/embed/" + id, nil } switch host { case "youtu.be": return youtube(parts[0]) case "youtube.com", "youtube-nocookie.com": switch { case len(parts) == 1 && parts[0] == "watch": return youtube(u.Query().Get("v")) case len(parts) == 2 && (parts[0] == "embed" || parts[0] == "shorts" || parts[0] == "live"): return youtube(parts[1]) } case "rutube.ru": // rutube.ru/video// и rutube.ru/play/embed/ id := "" if len(parts) == 2 && parts[0] == "video" { id = parts[1] } else if len(parts) == 3 && parts[0] == "play" && parts[1] == "embed" { id = parts[2] } if rutubeIDRE.MatchString(id) { return "https://rutube.ru/play/embed/" + id, nil } } return "", errVideoURL }