WuhuIslandTesting/Library/PackageCache/com.unity.addressables@1.21.12/Runtime/ResourceManager/Util/UnityWebRequestUtilities.cs

196 lines
7.4 KiB
C#
Raw Normal View History

2025-01-07 02:06:59 +01:00
using System;
using System.Text;
using UnityEngine.Networking;
namespace UnityEngine.ResourceManagement.Util
{
/// <summary>
/// Utility class for extracting information from UnityWebRequests.
/// </summary>
public class UnityWebRequestUtilities
{
/// <summary>
/// Determines if a web request resulted in an error.
/// </summary>
/// <param name="webReq">The web request.</param>
/// <param name="result"></param>
/// <returns>True if a web request resulted in an error.</returns>
public static bool RequestHasErrors(UnityWebRequest webReq, out UnityWebRequestResult result)
{
result = null;
if (webReq == null || !webReq.isDone)
return false;
#if UNITY_2020_1_OR_NEWER
switch (webReq.result)
{
case UnityWebRequest.Result.InProgress:
case UnityWebRequest.Result.Success:
return false;
case UnityWebRequest.Result.ConnectionError:
case UnityWebRequest.Result.ProtocolError:
case UnityWebRequest.Result.DataProcessingError:
result = new UnityWebRequestResult(webReq);
return true;
default:
throw new NotImplementedException($"Cannot determine whether UnityWebRequest succeeded or not from result : {webReq.result}");
}
#else
var isError = webReq.isHttpError || webReq.isNetworkError;
if (isError)
result = new UnityWebRequestResult(webReq);
return isError;
#endif
}
/// <summary>
/// Indicates if the requested AssetBundle is downloaded.
/// </summary>
/// <param name="op">The object returned from sending the web request.</param>
/// <returns>Returns true if the AssetBundle is downloaded.</returns>
public static bool IsAssetBundleDownloaded(UnityWebRequestAsyncOperation op)
{
#if ENABLE_ASYNC_ASSETBUNDLE_UWR
var handler = (DownloadHandlerAssetBundle)op.webRequest.downloadHandler;
if (handler != null && handler.autoLoadAssetBundle)
return handler.isDownloadComplete;
#endif
return op.isDone;
}
}
/// <summary>
/// Container class for the result of a unity web request.
/// </summary>
public class UnityWebRequestResult
{
/// <summary>
/// Creates a new instance of <see cref="UnityWebRequestResult"/>.
/// </summary>
/// <param name="request">The unity web request.</param>
public UnityWebRequestResult(UnityWebRequest request)
{
string error = request.error;
#if UNITY_2020_1_OR_NEWER
if (request.result == UnityWebRequest.Result.DataProcessingError && request.downloadHandler != null)
{
// https://docs.unity3d.com/ScriptReference/Networking.DownloadHandler-error.html
// When a UnityWebRequest ends with the result, UnityWebRequest.Result.DataProcessingError, the message describing the error is in the download handler
error = $"{error} : {request.downloadHandler.error}";
}
Result = request.result;
#endif
Error = error;
ResponseCode = request.responseCode;
Method = request.method;
Url = request.url;
}
/// <summary>Provides a new string object describing the result.</summary>
/// <returns>A newly allocated managed string.</returns>
public override string ToString()
{
var sb = new StringBuilder();
#if UNITY_2020_1_OR_NEWER
sb.AppendLine($"{Result} : {Error}");
#else
if (!string.IsNullOrEmpty(Error))
sb.AppendLine(Error);
#endif
if (ResponseCode > 0)
sb.AppendLine($"ResponseCode : {ResponseCode}, Method : {Method}");
sb.AppendLine($"url : {Url}");
return sb.ToString();
}
/// <summary>
/// A string explaining the error that occured.
/// </summary>
public string Error { get; set; }
/// <summary>
/// The numeric HTTP response code returned by the server, if any.
/// See <a href="https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequest-responseCode.html">documentation</a> for more details.
/// </summary>
public long ResponseCode { get; }
#if UNITY_2020_1_OR_NEWER
/// <summary>
/// The outcome of the request.
/// </summary>
public UnityWebRequest.Result Result { get; }
#endif
/// <summary>
/// The HTTP verb used by this UnityWebRequest, such as GET or POST.
/// </summary>
public string Method { get; }
/// <summary>
/// The target url of the request.
/// </summary>
public string Url { get; }
/// <summary>
/// Determines if the web request can be sent again based on its error.
/// </summary>
/// <returns>Returns true if the web request can be sent again.</returns>
public bool ShouldRetryDownloadError()
{
if (string.IsNullOrEmpty(Error))
return true;
if (Error == "Request aborted" ||
Error == "Unable to write data" ||
Error == "Malformed URL" ||
Error == "Out of memory" ||
Error == "Encountered invalid redirect (missing Location header?)" ||
Error == "Cannot modify request at this time" ||
Error == "Unsupported Protocol" ||
Error == "Destination host has an erroneous SSL certificate" ||
Error == "Unable to load SSL Cipher for verification" ||
Error == "SSL CA certificate error" ||
Error == "Unrecognized content-encoding" ||
Error == "Request already transmitted" ||
Error == "Invalid HTTP Method" ||
Error == "Header name contains invalid characters" ||
Error == "Header value contains invalid characters" ||
Error == "Cannot override system-specified headers"
#if UNITY_2022_1_OR_NEWER
|| Error == "Insecure connection not allowed"
#endif
)
return false;
/* Errors that can be retried:
"Unknown Error":
"No Internet Connection"
"Backend Initialization Error":
"Cannot resolve proxy":
"Cannot resolve destination host":
"Cannot connect to destination host":
"Access denied":
"Generic/unknown HTTP error":
"Unable to read data":
"Request timeout":
"Error during HTTP POST transmission":
"Unable to complete SSL connection":
"Redirect limit exceeded":
"Received no data in response":
"Destination host does not support SSL":
"Failed to transmit data":
"Failed to receive data":
"Login failed":
"SSL shutdown failed":
"Redirect limit is invalid":
"Not implemented":
"Data Processing Error, see Download Handler error":
*/
return true;
}
}
}