Skip to content

Commit

Permalink
upload
Browse files Browse the repository at this point in the history
  • Loading branch information
JDDKCN committed Nov 15, 2024
1 parent a44b2c7 commit a2f20d8
Show file tree
Hide file tree
Showing 6 changed files with 424 additions and 2 deletions.
252 changes: 252 additions & 0 deletions GetUrlHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
using System.IO.Compression;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;

namespace KCNLanzouDirectLink
{
internal static class GetUrlHelper
{
/// <summary>
/// 获取直链
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static async Task<string?> GetFullUrl(string url)
{
return await GetFinalUrlAsync(
ExtractAndCombineLinks(
await GetHtmlContentAsync(url)));
}

/// <summary>
/// 获取直链(加密)
/// </summary>
/// <param name="url"></param>
/// <param name="key"></param>
/// <returns></returns>
public static async Task<string?> GetFullUrl(string url, string key)
{
var postsign = ExtractPatternValue(
await GetHtmlContentAsync(url),
@"var\s*vidksek\s*=\s*['""]([^'""]+)['""]");
return await GetFinalUrlToPassAsync(await GetHtmlToPassContentAsync(postsign, key));
}

/// <summary>
/// 模拟浏览器请求Html
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static async Task<string?> GetHtmlContentAsync(string? url)
{
if (url == null)
return null;

using HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25");
client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
client.DefaultRequestHeaders.Add("Accept-Language", "zh-CN,zh;q=0.9");
client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Pragma", "no-cache");
client.DefaultRequestHeaders.Add("Upgrade-Insecure-Requests", "1");

url = ModifyUrlForTp(url);
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();

string contentEncoding = response.Content.Headers.ContentEncoding.ToString();

byte[] responseBytes = await response.Content.ReadAsByteArrayAsync();
return contentEncoding.Contains("gzip", StringComparison.OrdinalIgnoreCase)
? DecompressGzip(responseBytes)
: Encoding.UTF8.GetString(responseBytes);
}

/// <summary>
/// 模拟浏览器请求Html(加密)
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static async Task<string?> GetHtmlToPassContentAsync(string postsign, string key)
{
using HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25");
client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
client.DefaultRequestHeaders.Add("Accept-Language", "zh-CN,zh;q=0.9");
client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Pragma", "no-cache");
client.DefaultRequestHeaders.Add("Upgrade-Insecure-Requests", "1");
client.DefaultRequestHeaders.Add("Referer", "https://syxz.lanzoue.com");

var postData = new StringContent($"action=downprocess&sign={postsign}&p={key}", Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await client.PostAsync("https://syxz.lanzoue.com/ajaxm.php", postData);

string content = await response.Content.ReadAsStringAsync();

var jsonResponse = Newtonsoft.Json.Linq.JObject.Parse(content);
string? domain = jsonResponse["dom"]?.ToString();
string? url = jsonResponse["url"]?.ToString();

if (string.IsNullOrEmpty(domain) || string.IsNullOrEmpty(url))
return null;

string fullDownloadUrl = BuildDownloadUrl(domain, url);
return fullDownloadUrl;
}

/// <summary>
/// 获取中间链接
/// </summary>
/// <param name="htmlContent"></param>
/// <returns></returns>
public static string? ExtractAndCombineLinks(string? htmlContent)
{
if (htmlContent == null)
return null;

var vkjxld = ExtractPatternValue(htmlContent, @"var\s*vkjxld\s*=\s*['""]([^'""]+)['""]");
var hyggid = ExtractPatternValue(htmlContent, @"var\s*hyggid\s*=\s*['""]([^'""]+)['""]");

if (vkjxld == null || hyggid == null)
return null;

return vkjxld + hyggid;
}

/// <summary>
/// 获取最终直链
/// </summary>
/// <param name="intermediateUrl"></param>
/// <returns></returns>
public static async Task<string?> GetFinalUrlAsync(string? intermediateUrl)
{
if (string.IsNullOrEmpty(intermediateUrl))
return null;

HttpClientHandler handler = new HttpClientHandler
{
AllowAutoRedirect = false,
};

using HttpClient client = new HttpClient(handler);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate, br, zstd");
client.DefaultRequestHeaders.Add("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6");
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Host", "slssq.osslan.com:446");
client.DefaultRequestHeaders.Add("Sec-CH-UA", "\"Chromium\";v=\"130\", \"Microsoft Edge\";v=\"130\", \"Not?A_Brand\";v=\"99\"");
client.DefaultRequestHeaders.Add("Sec-CH-UA-Mobile", "?0");
client.DefaultRequestHeaders.Add("Sec-CH-UA-Platform", "\"Windows\"");
client.DefaultRequestHeaders.Add("Sec-Fetch-Dest", "document");
client.DefaultRequestHeaders.Add("Sec-Fetch-Mode", "navigate");
client.DefaultRequestHeaders.Add("Sec-Fetch-Site", "none");
client.DefaultRequestHeaders.Add("Sec-Fetch-User", "?1");
client.DefaultRequestHeaders.Add("Upgrade-Insecure-Requests", "1");
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0");

HttpResponseMessage response = await client.GetAsync(intermediateUrl);

if ((int)response.StatusCode < 300 || (int)response.StatusCode >= 400)
return null;

if (!response.Headers.Contains("Location"))
return null;

return response.Headers?.Location?.ToString();
}

/// <summary>
/// 获取最终直链(加密)
/// </summary>
/// <param name="intermediateUrl"></param>
/// <returns></returns>
public static async Task<string?> GetFinalUrlToPassAsync(string? intermediateUrl)
{
if (string.IsNullOrEmpty(intermediateUrl))
return null;

HttpClientHandler handler = new HttpClientHandler
{
AllowAutoRedirect = false,
};

using HttpClient client = new HttpClient(handler);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
client.DefaultRequestHeaders.Add("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6");
client.DefaultRequestHeaders.Add("Host", "develope-oss.lanzouc.com");
client.DefaultRequestHeaders.Add("Proxy-Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Upgrade-Insecure-Requests", "1");
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0");

HttpResponseMessage response = await client.GetAsync(intermediateUrl);

if ((int)response.StatusCode < 300 || (int)response.StatusCode >= 400)
return null;

if (!response.Headers.Contains("Location"))
return null;

return response.Headers?.Location?.ToString();
}

/// <summary>
/// 正则提取html值
/// </summary>
/// <param name="htmlContent"></param>
/// <param name="pattern"></param>
/// <returns></returns>
private static string? ExtractPatternValue(string htmlContent, string pattern)
{
var regex = new Regex(pattern, RegexOptions.Compiled);
var match = regex.Match(htmlContent);
return match.Success ? match.Groups[1].Value : null;
}

/// <summary>
/// 格式化Url
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static string ModifyUrlForTp(string url)
{
int lastSlashIndex = url.LastIndexOf('/');
if (lastSlashIndex == -1)
return url;
return url.Substring(0, lastSlashIndex + 1) + "tp/" + url.Substring(lastSlashIndex + 1);
}

/// <summary>
/// 格式化加密Url
/// </summary>
/// <param name="domain"></param>
/// <param name="url"></param>
/// <returns></returns>
public static string BuildDownloadUrl(string domain, string url)
{
string fullUrl = domain + "/file/" + WebUtility.UrlDecode(url);
return fullUrl;
}

/// <summary>
/// 解压Gzip数据
/// </summary>
/// <param name="gzipData"></param>
/// <returns></returns>
private static string DecompressGzip(byte[] gzipData)
{
using var ms = new MemoryStream(gzipData);
using var gzipStream = new GZipStream(ms, CompressionMode.Decompress);
using var reader = new StreamReader(gzipStream, Encoding.UTF8);
return reader.ReadToEnd();
}
}
}
47 changes: 47 additions & 0 deletions KCNLanzouDirectLink.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0;</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<!--
<Nullable>enable</Nullable>
-->

<!-- NuGet -->
<PackageId>KCNLanzouDirectLink</PackageId>
<Version>1.0.0</Version>
<Authors>剧毒的KCN(JDDKCN)</Authors>
<Company>KCN-Server</Company>
<Description>用于解析蓝奏云直链的C#原生实现类库。</Description>

<!-- 标签 -->
<PackageTags>Lanzou;DirectLink;Cloud;Download</PackageTags>

<!-- 许可证 -->
<PackageLicenseExpression>AGPL-3.0-or-later</PackageLicenseExpression>

<!-- 项目源 -->
<RepositoryUrl>https://github.com/JDDKCN/KCNLanzouDirectLink</RepositoryUrl>

<!-- 发布配置 -->
<Configuration>Release</Configuration>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>KCNLanzouDirectLink</Title>
<Copyright>Copyright ©2023-2024 剧毒的KCN, All Rights Reserved.</Copyright>
<PackageProjectUrl>https://github.com/JDDKCN/KCNLanzouDirectLink</PackageProjectUrl>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<PackageReleaseNotes>初次发布</PackageReleaseNotes>
<PackageReadmeFile>Readme.md</PackageReadmeFile>
<PackageIcon>favicon.png</PackageIcon>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

<ItemGroup>
<None Include="favicon.png" Pack="true" PackagePath="\" />
<None Include="Readme.md" Pack="true" PackagePath="\" />
</ItemGroup>

</Project>
25 changes: 25 additions & 0 deletions KCNLanzouDirectLink.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34728.123
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KCNLanzouDirectLink", "KCNLanzouDirectLink.csproj", "{B6774CDE-57D3-4B33-984D-23BF0B6BE6BE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B6774CDE-57D3-4B33-984D-23BF0B6BE6BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6774CDE-57D3-4B33-984D-23BF0B6BE6BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6774CDE-57D3-4B33-984D-23BF0B6BE6BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6774CDE-57D3-4B33-984D-23BF0B6BE6BE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {26E69CBA-8EC2-4A57-80C2-62D3E652E325}
EndGlobalSection
EndGlobal
29 changes: 29 additions & 0 deletions KCNLanzouLinkHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace KCNLanzouDirectLink
{
/// <summary>
/// 解析蓝奏云直链
/// </summary>
public static class KCNLanzouLinkHelper
{
/// <summary>
/// 获取蓝奏云分享链接的直链。
/// </summary>
/// <param name="url">蓝奏云分享链接</param>
/// <returns>返回解析后的直链,若失败则返回 null</returns>
public static async Task<string?> GetDirectLinkAsync(string url)
{
return await GetUrlHelper.GetFullUrl(url);
}

/// <summary>
/// 获取加密蓝奏云分享链接的直链。
/// </summary>
/// <param name="url">蓝奏云分享链接</param>
/// <param name="key">加密密钥</param>
/// <returns>返回解析后的直链,若失败则返回 null</returns>
public static async Task<string?> GetDirectLinkAsync(string url, string key)
{
return await GetUrlHelper.GetFullUrl(url, key);
}
}
}
Loading

0 comments on commit a2f20d8

Please sign in to comment.