using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; using System.Reflection; using System.Net; namespace Amazon.Runtime.Internal { /// /// This class is used to wrap around /// so that we can be backward compatible with unity 4.6 /// public class UnityWebRequestWrapper : IDisposable { private static Type unityWebRequestType; private static PropertyInfo[] unityWebRequestProperties; private static MethodInfo[] unityWebRequestMethods; //all methods private static MethodInfo setRequestHeaderMethod; private static MethodInfo sendMethod; private static MethodInfo getResponseHeadersMethod; private static MethodInfo isDoneGetMethod; private static MethodInfo downloadProgressGetMethod; private static MethodInfo uploadProgressGetMethod; private static MethodInfo isErrorGetMethod; private static MethodInfo downloadedBytesGetMethod; private static MethodInfo responseCodeGetMethod; private static MethodInfo downloadHandlerSetMethod; private static MethodInfo uploadHandlerSetMethod; private static MethodInfo errorGetMethod; // the instance of the unitywebrequest private object unityWebRequestInstance; private DownloadHandlerBufferWrapper downloadHandler; private UploadHandlerRawWrapper uploadHandler; static UnityWebRequestWrapper() { unityWebRequestType = Type.GetType("UnityEngine.Networking.UnityWebRequest, UnityEngine"); if (unityWebRequestType == null) { unityWebRequestType = Type.GetType("UnityEngine.Experimental.Networking.UnityWebRequest, UnityEngine"); } unityWebRequestMethods = unityWebRequestType.GetMethods(); unityWebRequestProperties = unityWebRequestType.GetProperties(); PropertyInfo isDoneProperty = unityWebRequestType.GetProperty("isDone"); PropertyInfo downloadProgressProperty = unityWebRequestType.GetProperty("downloadProgress"); PropertyInfo uploadProgressProperty = unityWebRequestType.GetProperty("uploadProgress"); PropertyInfo isErrorProperty = unityWebRequestType.GetProperty("isError"); if (isErrorProperty == null) { // VS 2017.1 update changed this property // https://github.com/aws/aws-sdk-net/pull/709 isErrorProperty = unityWebRequestType.GetProperty("isNetworkError"); } PropertyInfo downloadedBytesProperty = unityWebRequestType.GetProperty("downloadedBytes"); PropertyInfo responseCodeProperty = unityWebRequestType.GetProperty("responseCode"); PropertyInfo downloadHandlerPropery = unityWebRequestType.GetProperty("downloadHandler"); PropertyInfo uploadHandlerPropery = unityWebRequestType.GetProperty("uploadHandler"); PropertyInfo errorProperty = unityWebRequestType.GetProperty("error"); setRequestHeaderMethod = unityWebRequestType.GetMethod("SetRequestHeader"); sendMethod = unityWebRequestType.GetMethod("Send"); getResponseHeadersMethod = unityWebRequestType.GetMethod("GetResponseHeaders"); isDoneGetMethod = isDoneProperty.GetGetMethod(); isErrorGetMethod = isErrorProperty.GetGetMethod(); uploadProgressGetMethod = uploadProgressProperty.GetGetMethod(); downloadProgressGetMethod = downloadProgressProperty.GetGetMethod(); downloadedBytesGetMethod = downloadedBytesProperty.GetGetMethod(); responseCodeGetMethod = responseCodeProperty.GetGetMethod(); downloadHandlerSetMethod = downloadHandlerPropery.GetSetMethod(); uploadHandlerSetMethod = uploadHandlerPropery.GetSetMethod(); errorGetMethod = errorProperty.GetGetMethod(); } /// /// Create an instance of UnityWebRequestWrapper /// public UnityWebRequestWrapper() { if (!AWSConfigs.UnityWebRequestInitialized) throw new InvalidOperationException("UnityWebRequest is not supported in the current version of unity"); unityWebRequestInstance = Activator.CreateInstance(unityWebRequestType); } /// /// Create an instance of UnityWebRequestWrapper /// /// Url of the request /// The HTTP Methods public UnityWebRequestWrapper(string url, string method) { unityWebRequestInstance = Activator.CreateInstance(unityWebRequestType, url, method); } /// /// Create an instance of UnityWebRequestWrapper /// /// Url of the request /// The HTTP Methods /// Instance of /// Instance of public UnityWebRequestWrapper(string url, string method, DownloadHandlerBufferWrapper downloadHandler, UploadHandlerRawWrapper uploadHandler) { if (downloadHandler == null) throw new ArgumentNullException("downloadHandler"); if (uploadHandler == null) throw new ArgumentNullException("uploadHandler"); unityWebRequestInstance = Activator.CreateInstance(unityWebRequestType, url, method, downloadHandler.Instance, uploadHandler.Instance); } /// /// A flag that indicates is the UnityWebRequest is supported or not. /// internal static bool IsUnityWebRequestSupported { get { return unityWebRequestType != null; } } /// /// Get and Sets an instance of Download Handler /// public DownloadHandlerBufferWrapper DownloadHandler { set { if (value == null) throw new ArgumentNullException("value"); downloadHandlerSetMethod.Invoke(unityWebRequestInstance, new object[] { value.Instance }); this.downloadHandler = value; } get { return this.downloadHandler; } } /// /// Gets and Sets an instance of Upload Handler /// public UploadHandlerRawWrapper UploadHandler { set { if (value == null) throw new ArgumentNullException("value"); uploadHandlerSetMethod.Invoke(unityWebRequestInstance, new object[] { value.Instance }); this.uploadHandler = value; } get { return this.uploadHandler; } } /// /// Set the request Header /// /// the header key /// the header value public void SetRequestHeader(string key, string value) { setRequestHeaderMethod.Invoke(unityWebRequestInstance, new object[] { key, value }); } /// /// Make the http call /// /// public AsyncOperation Send() { return (AsyncOperation)sendMethod.Invoke(unityWebRequestInstance, null); } /// /// Boolean value indicating if the http operation is complete /// public bool IsDone { get { return (bool)isDoneGetMethod.Invoke(unityWebRequestInstance, null); } } /// /// The download progress /// public float DownloadProgress { get { return (float)downloadProgressGetMethod.Invoke(unityWebRequestInstance, null); } } /// /// The upload Progress /// public float UploadProgress { get { return (float)uploadProgressGetMethod.Invoke(unityWebRequestInstance, null); } } /// /// Number of bytes downloaded /// public ulong DownloadedBytes { get { return (ulong)downloadedBytesGetMethod.Invoke(unityWebRequestInstance, null); } } /// /// The response headers /// public Dictionary ResponseHeaders { get { return (Dictionary)getResponseHeadersMethod.Invoke(unityWebRequestInstance, null); } } /// /// The http status code /// public HttpStatusCode? StatusCode { get { object responseCodeObject = responseCodeGetMethod.Invoke(unityWebRequestInstance, null); long responseCode = (long)responseCodeObject; if (responseCode == -1) return null; return (HttpStatusCode)responseCode; } } /// /// returns if the http operation ended with an error /// public bool IsError { get { return (bool)isErrorGetMethod.Invoke(unityWebRequestInstance, null); } } /// /// returns the error string in case the http operation ended with an error /// public string Error { get { return (string)errorGetMethod.Invoke(unityWebRequestInstance, null); } } #region IDisposable Support private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { var disposableWebRequest = unityWebRequestInstance as IDisposable; if (disposableWebRequest != null) disposableWebRequest.Dispose(); } unityWebRequestInstance = null; disposedValue = true; } } // This code added to correctly implement the disposable pattern. public void Dispose() { Dispose(true); } #endregion } public class DownloadHandlerBufferWrapper : IDisposable { private static Type downloadHandlerBufferType; private static PropertyInfo[] downloadHandlerBufferProperties; private static MethodInfo[] downloadHandlerBufferMethods; private static PropertyInfo dataProperty; private static MethodInfo dataGetMethod; /// /// Instance of /// public object Instance { get; private set; } static DownloadHandlerBufferWrapper() { downloadHandlerBufferType = Type.GetType("UnityEngine.Networking.DownloadHandlerBuffer, UnityEngine"); if(downloadHandlerBufferType == null) { downloadHandlerBufferType = Type.GetType("UnityEngine.Experimental.Networking.DownloadHandlerBuffer, UnityEngine"); } downloadHandlerBufferMethods = downloadHandlerBufferType.GetMethods(); downloadHandlerBufferProperties = downloadHandlerBufferType.GetProperties(); dataProperty = downloadHandlerBufferType.GetProperty("data"); dataGetMethod = dataProperty.GetGetMethod(); } /// /// Creates an new instance of /// public DownloadHandlerBufferWrapper() { Instance = Activator.CreateInstance(downloadHandlerBufferType); } /// /// Returns the response data as a array of bytes /// public byte[] Data { get { return (byte[])dataGetMethod.Invoke(Instance, null); } } #region IDisposable Support private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { var disposableHandler = Instance as IDisposable; if (disposableHandler != null) disposableHandler.Dispose(); } Instance = null; disposedValue = true; } } // This code added to correctly implement the disposable pattern. public void Dispose() { Dispose(true); } #endregion } public class UploadHandlerRawWrapper : IDisposable { private static Type uploadHandlerRawType; /// /// Instance of /// public object Instance { get; private set; } static UploadHandlerRawWrapper() { uploadHandlerRawType = Type.GetType("UnityEngine.Networking.UploadHandlerRaw, UnityEngine"); if(uploadHandlerRawType == null) { uploadHandlerRawType = Type.GetType("UnityEngine.Experimental.Networking.UploadHandlerRaw, UnityEngine"); } } /// /// Creates an instance of /// /// public UploadHandlerRawWrapper(byte[] data) { Instance = Activator.CreateInstance(uploadHandlerRawType, data); } #region IDisposable Support private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { var disposableHandler = Instance as IDisposable; if (disposableHandler != null) disposableHandler.Dispose(); } Instance = null; disposedValue = true; } } // This code added to correctly implement the disposable pattern. public void Dispose() { Dispose(true); } #endregion } }