private static async Task <Response> ProcessRequestAsync(UnityWebRequest webRequest, int timeout, Dictionary <string, string> headers = null, bool readResponseData = false, CertificateHandler certificateHandler = null, bool disposeCertificateHandlerOnDispose = true) { if (timeout > 0) { webRequest.timeout = timeout; } if (headers != null) { foreach (var header in headers) { webRequest.SetRequestHeader(header.Key, header.Value); } } // HACK: Workaround for extra quotes around boundary. if (webRequest.method == UnityWebRequest.kHttpVerbPOST || webRequest.method == UnityWebRequest.kHttpVerbPUT) { string contentType = webRequest.GetRequestHeader("Content-Type"); if (contentType != null) { contentType = contentType.Replace("\"", ""); webRequest.SetRequestHeader("Content-Type", contentType); } } webRequest.certificateHandler = certificateHandler; webRequest.disposeCertificateHandlerOnDispose = disposeCertificateHandlerOnDispose; await webRequest.SendWebRequest(); long responseCode = webRequest.responseCode; Func <byte[]> downloadHandlerDataAction = () => webRequest.downloadHandler?.data; #if UNITY_2020_1_OR_NEWER if (webRequest.result == UnityWebRequest.Result.ConnectionError || webRequest.result == UnityWebRequest.Result.ProtocolError) #else if (webRequest.isNetworkError || webRequest.isHttpError) #endif // UNITY_2020_1_OR_NEWER { if (responseCode == 401) { return(new Response(false, "Invalid Credentials", null, responseCode)); } if (webRequest.GetResponseHeaders() == null) { return(new Response(false, "Device Unavailable", null, responseCode)); } string responseHeaders = webRequest.GetResponseHeaders().Aggregate(string.Empty, (current, header) => $"\n{header.Key}: {header.Value}"); string downloadHandlerText = await ResponseUtils.BytesToString(downloadHandlerDataAction.Invoke()); Debug.LogError($"REST Error: {responseCode}\n{downloadHandlerText}{responseHeaders}"); return(new Response(false, $"{responseHeaders}\n{downloadHandlerText}", downloadHandlerDataAction.Invoke(), responseCode)); } if (readResponseData) { return(new Response(true, await ResponseUtils.BytesToString(downloadHandlerDataAction.Invoke()), downloadHandlerDataAction.Invoke(), responseCode)); } else // This option can be used only if action will be triggered in the same scope as the webrequest { return(new Response(true, downloadHandlerDataAction, responseCode)); } }