优化BaseUrl的选择(自动处理302)

This commit is contained in:
nilaoda 2022-07-20 14:21:28 +08:00
parent 113e8f5010
commit 34fc09d73b
7 changed files with 74 additions and 44 deletions

View File

@ -87,6 +87,15 @@ namespace N_m3u8DL_RE.Common.Resource {
} }
} }
/// <summary>
/// 查找类似 Add Params of input Url to segments, useful for some websites, such as kakao.com 的本地化字符串。
/// </summary>
public static string cmd_appendUrlParams {
get {
return ResourceManager.GetString("cmd_appendUrlParams", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Automatically selects the best tracks of all types 的本地化字符串。 /// 查找类似 Automatically selects the best tracks of all types 的本地化字符串。
/// </summary> /// </summary>
@ -241,6 +250,15 @@ namespace N_m3u8DL_RE.Common.Resource {
} }
} }
/// <summary>
/// 查找类似 Write meta json after parsed 的本地化字符串。
/// </summary>
public static string cmd_writeMetaJson {
get {
return ResourceManager.GetString("cmd_writeMetaJson", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Fetch: 的本地化字符串。 /// 查找类似 Fetch: 的本地化字符串。
/// </summary> /// </summary>

View File

@ -221,4 +221,10 @@
<data name="cmd_skipDownload" xml:space="preserve"> <data name="cmd_skipDownload" xml:space="preserve">
<value>Skip download</value> <value>Skip download</value>
</data> </data>
<data name="cmd_writeMetaJson" xml:space="preserve">
<value>Write meta json after parsed</value>
</data>
<data name="cmd_appendUrlParams" xml:space="preserve">
<value>Add Params of input Url to segments, useful for some websites, such as kakao.com</value>
</data>
</root> </root>

View File

@ -241,4 +241,10 @@
<data name="cmd_skipDownload" xml:space="preserve"> <data name="cmd_skipDownload" xml:space="preserve">
<value>跳过下载</value> <value>跳过下载</value>
</data> </data>
<data name="cmd_writeMetaJson" xml:space="preserve">
<value>解析后的信息是否输出json文件</value>
</data>
<data name="cmd_appendUrlParams" xml:space="preserve">
<value>将输入Url的Params添加至分片, 对某些网站很有用, 例如 kakao.com</value>
</data>
</root> </root>

View File

@ -221,4 +221,10 @@
<data name="cmd_skipDownload" xml:space="preserve"> <data name="cmd_skipDownload" xml:space="preserve">
<value>跳過下載</value> <value>跳過下載</value>
</data> </data>
<data name="cmd_writeMetaJson" xml:space="preserve">
<value>解析後的信息是否輸出json文件</value>
</data>
<data name="cmd_appendUrlParams" xml:space="preserve">
<value>將輸入Url的Params添加至分片, 對某些網站很有用, 例如 kakao.com</value>
</data>
</root> </root>

View File

@ -49,58 +49,24 @@ namespace N_m3u8DL_RE.Common.Util
} }
} }
Logger.Debug(webRequest.Headers.ToString()); Logger.Debug(webRequest.Headers.ToString());
//手动处理跳转以免自定义Headers丢失
var webResponse = await AppHttpClient.SendAsync(webRequest, HttpCompletionOption.ResponseHeadersRead); var webResponse = await AppHttpClient.SendAsync(webRequest, HttpCompletionOption.ResponseHeadersRead);
if (webResponse.StatusCode == HttpStatusCode.Found || webResponse.StatusCode == HttpStatusCode.Moved) if (webResponse.StatusCode == HttpStatusCode.Found || webResponse.StatusCode == HttpStatusCode.Moved)
{ {
HttpResponseHeaders respHeaders = webResponse.Headers; HttpResponseHeaders respHeaders = webResponse.Headers;
Logger.Debug(respHeaders.ToString()); Logger.Debug(respHeaders.ToString());
if (respHeaders != null && respHeaders.Location != null) if (respHeaders != null && respHeaders.Location != null && respHeaders.Location.AbsoluteUri != url)
{ {
var redirectedUrl = respHeaders.Location.AbsoluteUri; var redirectedUrl = respHeaders.Location.AbsoluteUri;
return await DoGetAsync(redirectedUrl, headers); return await DoGetAsync(redirectedUrl, headers);
} }
} }
//手动将跳转后的URL设置进去, 用于后续取用
webResponse.Headers.Location = new Uri(url);
webResponse.EnsureSuccessStatusCode(); webResponse.EnsureSuccessStatusCode();
return webResponse; return webResponse;
} }
//重定向
public static async Task<string> Get302Async(string url, Dictionary<string, string>? headers = null)
{
Logger.Debug(ResString.fetch + url);
var handler = new HttpClientHandler()
{
AllowAutoRedirect = false
};
string redirectedUrl = url;
using (HttpClient client = new HttpClient(handler))
{
if (headers != null)
{
foreach (var item in headers)
{
client.DefaultRequestHeaders.TryAddWithoutValidation(item.Key, item.Value);
}
}
using (HttpResponseMessage response = await client.GetAsync(url))
using (HttpContent content = response.Content)
{
Logger.Debug(ResString.fetch + response.Headers);
if (response.StatusCode == HttpStatusCode.Found || response.StatusCode == HttpStatusCode.Moved)
{
HttpResponseHeaders respHeaders = response.Headers;
if (respHeaders != null && respHeaders.Location != null)
{
redirectedUrl = respHeaders.Location.AbsoluteUri;
}
}
}
}
return redirectedUrl;
}
public static async Task<byte[]> GetBytesAsync(string url, Dictionary<string, string>? headers = null) public static async Task<byte[]> GetBytesAsync(string url, Dictionary<string, string>? headers = null)
{ {
byte[] bytes = new byte[0]; byte[] bytes = new byte[0];
@ -110,6 +76,12 @@ namespace N_m3u8DL_RE.Common.Util
return bytes; return bytes;
} }
/// <summary>
/// 获取网页源码
/// </summary>
/// <param name="url"></param>
/// <param name="headers"></param>
/// <returns></returns>
public static async Task<string> GetWebSourceAsync(string url, Dictionary<string, string>? headers = null) public static async Task<string> GetWebSourceAsync(string url, Dictionary<string, string>? headers = null)
{ {
string htmlCode = string.Empty; string htmlCode = string.Empty;
@ -119,6 +91,21 @@ namespace N_m3u8DL_RE.Common.Util
return htmlCode; return htmlCode;
} }
/// <summary>
/// 获取网页源码和跳转后的URL
/// </summary>
/// <param name="url"></param>
/// <param name="headers"></param>
/// <returns>(Source Code, RedirectedUrl)</returns>
public static async Task<(string, string)> GetWebSourceAndNewUrlAsync(string url, Dictionary<string, string>? headers = null)
{
string htmlCode = string.Empty;
var webResponse = await DoGetAsync(url, headers);
htmlCode = await webResponse.Content.ReadAsStringAsync();
Logger.Debug(htmlCode);
return (htmlCode, webResponse.Headers.Location != null ? webResponse.Headers.Location.AbsoluteUri : url);
}
public static async Task<string> GetPostResponseAsync(string Url, byte[] postData) public static async Task<string> GetPostResponseAsync(string Url, byte[] postData)
{ {
string htmlCode = string.Empty; string htmlCode = string.Empty;

View File

@ -31,13 +31,18 @@ namespace N_m3u8DL_RE.Parser.Extractor
{ {
this.ParserConfig = parserConfig; this.ParserConfig = parserConfig;
this.M3u8Url = parserConfig.Url ?? string.Empty; this.M3u8Url = parserConfig.Url ?? string.Empty;
if (!string.IsNullOrEmpty(parserConfig.BaseUrl)) this.SetBaseUrl();
}
private void SetBaseUrl()
{
if (!string.IsNullOrEmpty(ParserConfig.BaseUrl))
{ {
this.BaseUrl = parserConfig.BaseUrl; this.BaseUrl = ParserConfig.BaseUrl;
} }
else else
{ {
this.BaseUrl = parserConfig.BaseUrl = this.M3u8Url; this.BaseUrl = ParserConfig.BaseUrl = this.M3u8Url;
} }
} }
@ -499,9 +504,11 @@ namespace N_m3u8DL_RE.Parser.Extractor
} }
else if (url.StartsWith("http")) else if (url.StartsWith("http"))
{ {
this.M3u8Content = await HTTPUtil.GetWebSourceAsync(url, ParserConfig.Headers); (this.M3u8Content, url) = await HTTPUtil.GetWebSourceAndNewUrlAsync(url, ParserConfig.Headers);
} }
this.M3u8Url = this.BaseUrl = url;
this.M3u8Url = url;
this.SetBaseUrl();
this.PreProcessContent(); this.PreProcessContent();
} }

View File

@ -42,7 +42,7 @@ namespace N_m3u8DL_RE.Parser
} }
else if (url.StartsWith("http")) else if (url.StartsWith("http"))
{ {
this.rawText = HTTPUtil.GetWebSourceAsync(url, parserConfig.Headers).Result; (this.rawText, url) = HTTPUtil.GetWebSourceAndNewUrlAsync(url, parserConfig.Headers).Result;
parserConfig.Url = url; parserConfig.Url = url;
} }
else if (File.Exists(url)) else if (File.Exists(url))