Baseline: WPF/Avalonia/Cli/Core + plans (BROWSER_FEATURES_PLAN v2, MOBILE_PLAN v1)

This commit is contained in:
Yun Chan 2026-08-15 11:59:25 +09:00
commit 21b7c4d8bd
60 changed files with 6581 additions and 0 deletions

View file

@ -0,0 +1,51 @@
using System.Text;
namespace VideoDownloader.Core.Social;
/// <summary>
/// yt-dlp 가 읽을 수 있는 Netscape cookies.txt 형식으로 쿠키를 내보낸다.
/// 로그인/연령제한/멤버 콘텐츠(인스타·X 등) 를 위해 앱(WebView2) 의 세션 쿠키를 yt-dlp 에 전달.
/// </summary>
public static class CookieJarWriter
{
// ★ BOM 금지: Encoding.UTF8 은 EF BB BF(BOM) 를 붙이는데, yt-dlp 가 첫 줄
// "# Netscape HTTP Cookie File" 헤더를 인식하지 못해("does not look like a Netscape format
// cookies file" + "invalid length 1") 쿠키 파일 전체를 거부한다.
// → preamble 을 emit 하지 않는 UTF-8 인코딩 사용.
private static readonly Encoding NoBomUtf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
public static void Write(string path, IEnumerable<CookieRecord> cookies)
{
var sb = new StringBuilder();
sb.AppendLine("# Netscape HTTP Cookie File");
sb.AppendLine("# This is generated by VideoDownloader. Do not edit.");
foreach (var c in cookies)
{
// 필드: domain | flag(도메인 전체 적용) | path | secure | expiration | name | value
string domain = Sanitize(c.Domain);
if (string.IsNullOrEmpty(domain)) continue; // 도메인 없는 쿠키는 7-필드 레이아웃 보호를 위해 건너뜀
string name = Sanitize(c.Name);
string value = Sanitize(c.Value);
if (name.Length == 0 && value.Length == 0) continue;
bool subdomains = domain.StartsWith('.');
// HttpOnly 쿠키는 줄 앞에 "#HttpOnly_" 접두 — yt-dlp 가 http_only 플래그로 인식.
// (YouTube 의 __Secure-* / SID 계열 인증 쿠키가 대부분 HttpOnly.)
if (c.HttpOnly) sb.Append("#HttpOnly_");
sb.Append(domain).Append('\t');
sb.Append(subdomains ? "TRUE" : "FALSE").Append('\t');
sb.Append(string.IsNullOrEmpty(c.Path) ? "/" : Sanitize(c.Path)).Append('\t');
sb.Append(c.Secure ? "TRUE" : "FALSE").Append('\t');
sb.Append(c.Expires > 0 ? c.Expires : 0).Append('\t');
sb.Append(name).Append('\t');
sb.Append(value);
sb.AppendLine();
}
File.WriteAllText(path, sb.ToString(), NoBomUtf8);
}
/// <summary>필드 구분자(tab) 와 줄바꿈(CR/LF) 이 값 안에 들어가 7-필드 레이아웃이 깨지는 것을 방지.</summary>
private static string Sanitize(string s) =>
string.IsNullOrEmpty(s) ? s : s.Replace('\t', ' ').Replace('\r', ' ').Replace('\n', ' ');
}