using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using RudderSdk.Core; using UnityEngine.Networking; namespace RudderSdk.Unity { public sealed class UnityWebRequestExecutor : IUnityRequestExecutor { private const int DefaultTimeoutSeconds = 10; private readonly int _timeoutSeconds; public UnityWebRequestExecutor(int timeoutSeconds = DefaultTimeoutSeconds) { _timeoutSeconds = timeoutSeconds > 0 ? timeoutSeconds : DefaultTimeoutSeconds; } public async Task SendAsync( string method, string url, string body, IReadOnlyDictionary headers, CancellationToken cancellationToken = default) { using (var request = new UnityWebRequest(url, method)) { if (!string.IsNullOrEmpty(body)) { var payload = System.Text.Encoding.UTF8.GetBytes(body); request.uploadHandler = new UploadHandlerRaw(payload); } request.downloadHandler = new DownloadHandlerBuffer(); request.timeout = _timeoutSeconds; foreach (var header in headers) { request.SetRequestHeader(header.Key, header.Value); } var operation = request.SendWebRequest(); var completion = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); operation.completed += _ => completion.TrySetResult(true); using (cancellationToken.Register(() => completion.TrySetCanceled(cancellationToken))) { await completion.Task; } if (request.result == UnityWebRequest.Result.ConnectionError) { throw new RudderNetworkException(request.error); } if (request.result == UnityWebRequest.Result.ProtocolError) { var responseBody = request.downloadHandler.text; throw new UnityRequestException( (int)request.responseCode, responseBody, request.error + ": " + responseBody); } return request.downloadHandler?.text ?? string.Empty; } } } }