using System; using System.Collections.Generic; using System.IO; using UnityEngine.Networking; using Unity.Services.Core.Internal; using Unity.Services.Core.Networking.Internal; namespace Unity.Services.Core.Networking { class UnityWebRequestClient : IHttpClient { /// /// Key: The identifier of the service. /// Value: The configuration of the HTTP client for the service. /// readonly Dictionary m_ServiceIdToConfig = new Dictionary(); /// public string GetBaseUrlFor(string serviceId) { return m_ServiceIdToConfig[serviceId].BaseUrl; } /// public HttpOptions GetDefaultOptionsFor(string serviceId) { return m_ServiceIdToConfig[serviceId].DefaultOptions; } /// public HttpRequest CreateRequestForService(string serviceId, string resourcePath) { var serviceConfig = m_ServiceIdToConfig[serviceId]; var url = CombinePaths(serviceConfig.BaseUrl, resourcePath); var request = new HttpRequest() .SetUrl(url) .SetOptions(serviceConfig.DefaultOptions); return request; } internal static string CombinePaths(string path1, string path2) { //Replace '\' by '/' to unify separators used in the URL and make sure it is compatible with all platforms. return Path.Combine(path1, path2) .Replace('\\', '/'); } /// public IAsyncOperation Send(HttpRequest request) { var operation = new AsyncOperation(); operation.SetInProgress(); try { var webRequest = ConvertToWebRequest(request); webRequest.SendWebRequest() .completed += OnWebRequestCompleted; } catch (Exception reason) { operation.Fail(reason); } return operation; void OnWebRequestCompleted(UnityEngine.AsyncOperation unityOperation) { var callbackWebRequest = ((UnityWebRequestAsyncOperation)unityOperation).webRequest; var response = ConvertToResponse(callbackWebRequest) .SetRequest(request); var responseHandle = new ReadOnlyHttpResponse(response); callbackWebRequest.Dispose(); operation.Succeed(responseHandle); } } static UnityWebRequest ConvertToWebRequest(HttpRequest request) { var webRequest = new UnityWebRequest(request.Url, request.Method) { downloadHandler = new DownloadHandlerBuffer(), redirectLimit = request.Options.RedirectLimit, timeout = request.Options.RequestTimeoutInSeconds }; if (!(request.Body is null) && request.Body.Length > 0) { webRequest.uploadHandler = new UploadHandlerRaw(request.Body); } if (!(request.Headers is null)) { foreach (var header in request.Headers) { webRequest.SetRequestHeader(header.Key, header.Value); } } return webRequest; } static HttpResponse ConvertToResponse(UnityWebRequest webRequest) { var response = new HttpResponse() .SetHeaders(webRequest.GetResponseHeaders()) .SetData(webRequest.downloadHandler?.data) .SetStatusCode(webRequest.responseCode) .SetErrorMessage(webRequest.error) #if UNITY_2020_2_OR_NEWER .SetIsHttpError(webRequest.result == UnityWebRequest.Result.ProtocolError) .SetIsNetworkError(webRequest.result == UnityWebRequest.Result.ConnectionError); #else .SetIsHttpError(webRequest.isHttpError) .SetIsNetworkError(webRequest.isNetworkError); #endif return response; } internal void SetServiceConfig(HttpServiceConfig config) { m_ServiceIdToConfig[config.ServiceId] = config; } } }