using System.Threading; using System.Threading.Tasks; using RudderSdk.Core; using RudderSdk.Core.Abstractions; using UnityEngine.Networking; namespace RudderSdk.Unity { internal sealed class UnityUploadTransport : IUploadTransport { private const int DefaultTimeoutSeconds = 10; private readonly int _timeoutSeconds; public UnityUploadTransport(int timeoutSeconds = DefaultTimeoutSeconds) { _timeoutSeconds = timeoutSeconds > 0 ? timeoutSeconds : DefaultTimeoutSeconds; } public async Task PutAsync(string url, byte[] data, string contentType, CancellationToken cancellationToken = default) { using (var request = UnityWebRequest.Put(url, data ?? System.Array.Empty())) { if (!string.IsNullOrEmpty(contentType)) request.SetRequestHeader("Content-Type", contentType); request.timeout = _timeoutSeconds; var operation = request.SendWebRequest(); var completion = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); operation.completed += _ => completion.TrySetResult(true); using (cancellationToken.Register(() => { request.Abort(); completion.TrySetCanceled(cancellationToken); })) { await completion.Task.ConfigureAwait(false); } if (request.result == UnityWebRequest.Result.ConnectionError) { throw new RudderNetworkException(request.error); } if (request.result == UnityWebRequest.Result.ProtocolError) { throw new RudderApiException( (int)request.responseCode, string.Empty, request.error + ": " + request.downloadHandler?.text); } } } } }