2026-01-05 19:44:10 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using UnityEngine.Networking;
|
|
|
|
|
|
|
|
|
|
|
|
namespace YooAsset
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// UnityWebRequest HEAD 请求下载器
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 仅获取响应头信息,不下载实际内容。
|
|
|
|
|
|
/// 用于检查资源是否存在、获取资源大小、检查缓存有效性等场景。
|
|
|
|
|
|
/// </remarks>
|
2026-01-12 11:09:27 +08:00
|
|
|
|
internal sealed class UnityWebRequestHead : UnityWebRequestBase, IDownloadHeadRequest
|
2026-01-05 19:44:10 +08:00
|
|
|
|
{
|
2026-01-27 17:32:20 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 缓存的响应头(请求完成后从 WebRequest 复制)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// WebRequest 释放后无法获取响应头,因此需要提前缓存。
|
|
|
|
|
|
/// </remarks>
|
2026-01-05 19:44:10 +08:00
|
|
|
|
private Dictionary<string, string> _cachedResponseHeaders;
|
2026-01-27 17:32:20 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 数据下载参数
|
|
|
|
|
|
/// </summary>
|
2026-01-05 19:44:10 +08:00
|
|
|
|
private readonly DownloadDataRequestArgs _args;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取 ETag 响应头
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string ETag
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return GetResponseHeader("ETag"); }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取 Last-Modified 响应头
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string LastModified
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return GetResponseHeader("Last-Modified"); }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取 Content-Type 响应头
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string ContentType
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return GetResponseHeader("Content-Type"); }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取 Content-Length 响应头
|
|
|
|
|
|
/// 预期下载的总字节数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public long ContentLength
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
string contentLengthStr = GetResponseHeader("Content-Length");
|
|
|
|
|
|
if (string.IsNullOrEmpty(contentLengthStr))
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
if (long.TryParse(contentLengthStr, out long contentLength))
|
|
|
|
|
|
{
|
|
|
|
|
|
return contentLength;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构造 HEAD 请求下载器
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="args">数据下载参数</param>
|
|
|
|
|
|
/// <param name="webRequestCreator">UnityWebRequest 创建器(可选)</param>
|
2026-01-12 11:09:27 +08:00
|
|
|
|
public UnityWebRequestHead(DownloadDataRequestArgs args, UnityWebRequestCreator webRequestCreator)
|
2026-01-27 17:32:20 +08:00
|
|
|
|
: base(args.Url, webRequestCreator)
|
2026-01-05 19:44:10 +08:00
|
|
|
|
{
|
|
|
|
|
|
_args = args;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取响应头信息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="name">响应头名称(不区分大小写)</param>
|
|
|
|
|
|
/// <returns>响应头的值,如果不存在或请求未完成则返回 null</returns>
|
|
|
|
|
|
public string GetResponseHeader(string name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_cachedResponseHeaders == null)
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
|
|
// 注意:UnityWebRequest 的响应头 key 是小写的
|
|
|
|
|
|
string lowerName = name.ToLowerInvariant();
|
|
|
|
|
|
if (_cachedResponseHeaders.TryGetValue(lowerName, out string value))
|
|
|
|
|
|
return value;
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建 UnityWebRequest
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
protected override void CreateWebRequest()
|
|
|
|
|
|
{
|
2026-01-27 17:32:20 +08:00
|
|
|
|
_webRequest = CreateHeadWebRequest(Url);
|
2026-01-05 19:44:10 +08:00
|
|
|
|
_webRequest.downloadHandler = null; // HEAD 请求不需要 DownloadHandler
|
2026-01-12 11:09:27 +08:00
|
|
|
|
ConfigureRequest(_args.Timeout, _args.WatchdogTimeout, _args.Headers);
|
2026-01-05 19:44:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 请求成功时的回调
|
|
|
|
|
|
/// </summary>
|
2026-01-27 17:32:20 +08:00
|
|
|
|
protected override void OnRequestSucceeded()
|
2026-01-05 19:44:10 +08:00
|
|
|
|
{
|
|
|
|
|
|
var headers = _webRequest.GetResponseHeaders();
|
|
|
|
|
|
if (headers != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_cachedResponseHeaders = new Dictionary<string, string>(headers.Count, StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
|
foreach (var kvp in headers)
|
|
|
|
|
|
{
|
|
|
|
|
|
string name = kvp.Key.ToLowerInvariant();
|
|
|
|
|
|
string value = kvp.Value;
|
|
|
|
|
|
_cachedResponseHeaders[name] = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|