// ---------[ VALUE INTERPRETATION AND APPLICATION ]--------- private static int ParseDateHeaderAsTimeStamp(UnityWebRequest webRequest) { var dateHeaderValue = webRequest.GetResponseHeader("Date"); // Examples: // Thu, 28 Feb 2019 07:04:38 GMT // Fri, 01 Mar 2019 01:16:49 GMT string timeFormat = "ddd, dd MMM yyyy HH:mm:ss 'GMT'"; DateTime time; if (!string.IsNullOrEmpty(dateHeaderValue) && DateTime.TryParseExact(dateHeaderValue, timeFormat, System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat, System.Globalization.DateTimeStyles.AssumeUniversal, out time)) { // NOTE(@jackson): For some reason, System.Globalization.DateTimeStyles.AssumeUniversal // is ignored(?) in TryParseExact, so it needs to be set as universal after the fact. time = DateTime.SpecifyKind(time, System.DateTimeKind.Utc); return(ServerTimeStamp.FromUTCDateTime(time)); } return(ServerTimeStamp.Now); }
private static void OnImageDownloadCompleted(UnityWebRequestAsyncOperation operation, ImageRequest request) { UnityWebRequest webRequest = operation.webRequest; request.isDone = true; if (webRequest.isNetworkError || webRequest.isHttpError) { request.error = WebRequestError.GenerateFromWebRequest(webRequest); request.NotifyFailed(); } else { #if DEBUG if (PluginSettings.data.logAllRequests) { var responseTimeStamp = ServerTimeStamp.Now; Debug.Log("IMAGE DOWNLOAD SUCEEDED" + "\nDownload completed at: " + ServerTimeStamp.ToLocalDateTime(responseTimeStamp) + "\nURL: " + webRequest.url); } #endif request.imageTexture = (webRequest.downloadHandler as DownloadHandlerTexture).texture; request.NotifySucceeded(); } }
private static void OnImageDownloadCompleted(UnityWebRequestAsyncOperation operation, ImageRequest request) { UnityWebRequest webRequest = operation.webRequest; request.isDone = true; if (webRequest.isNetworkError || webRequest.isHttpError) { request.error = WebRequestError.GenerateFromWebRequest(webRequest); request.NotifyFailed(); } else { #if DEBUG if (DownloadClient.logAllRequests) { var responseTimeStamp = ServerTimeStamp.Now; Debug.Log(String.Format("{0} REQUEST SUCEEDED\nResponse received at: {1} [{2}]\nURL: {3}\nResponse: {4}\n", webRequest.method.ToUpper(), ServerTimeStamp.ToLocalDateTime(responseTimeStamp), responseTimeStamp, webRequest.url, webRequest.downloadHandler.text)); } #endif request.imageTexture = (webRequest.downloadHandler as DownloadHandlerTexture).texture; request.NotifySucceeded(); } }
private static void OnModBinaryRequestCompleted(UnityWebRequestAsyncOperation operation, ModBinaryRequest request) { UnityWebRequest webRequest = operation.webRequest; request.isDone = true; if (webRequest.isNetworkError || webRequest.isHttpError) { request.error = WebRequestError.GenerateFromWebRequest(webRequest); request.NotifyFailed(); } else { #if DEBUG if (GlobalSettings.LOG_ALL_WEBREQUESTS) { var responseTimeStamp = ServerTimeStamp.Now; Debug.Log("DOWNLOAD SUCEEDED" + "\nDownload completed at: " + ServerTimeStamp.ToLocalDateTime(responseTimeStamp) + "\nURL: " + webRequest.url + "\nFilePath: " + request.binaryFilePath); } #endif try { if (File.Exists(request.binaryFilePath)) { File.Delete(request.binaryFilePath); } File.Move(request.binaryFilePath + ".download", request.binaryFilePath); } catch (Exception e) { string warningInfo = ("[mod.io] Failed to save mod binary." + "\nFile: " + request.binaryFilePath + "\n\n"); Debug.LogWarning(warningInfo + Utility.GenerateExceptionDebugString(e)); request.NotifyFailed(); } request.NotifySucceeded(); } }
// ---------[ HELPER FUNCTIONS ]--------- public string ToUnityDebugString() { var debugString = new System.Text.StringBuilder(); string headerString = (this.webRequest == null ? "REQUEST FAILED LOCALLY" : this.webRequest.method.ToUpper() + " REQUEST FAILED"); debugString.AppendLine(headerString); if (this.webRequest != null) { debugString.AppendLine("URL: " + this.webRequest.url); debugString.AppendLine("TimeStamp: " + this.timeStamp + " (" + ServerTimeStamp.ToLocalDateTime(this.timeStamp) + ")"); debugString.AppendLine("ResponseCode: " + this.webRequest.responseCode.ToString()); var responseHeaders = webRequest.GetResponseHeaders(); if (responseHeaders != null && responseHeaders.Count > 0) { debugString.AppendLine("Response Headers:"); foreach (var kvp in responseHeaders) { debugString.AppendLine("- [" + kvp.Key + "] " + kvp.Value); } } debugString.AppendLine("ErrorMessage: " + this.errorMessage); if (this.fieldValidationMessages != null && this.fieldValidationMessages.Count > 0) { debugString.AppendLine("Field Validation Messages:"); foreach (var kvp in fieldValidationMessages) { debugString.AppendLine("- [" + kvp.Key + "] " + kvp.Value); } } debugString.AppendLine(".isAuthenticationInvalid = " + this.isAuthenticationInvalid.ToString()); debugString.AppendLine(".isServerUnreachable = " + this.isServerUnreachable.ToString()); debugString.AppendLine(".isRequestUnresolvable = " + this.isRequestUnresolvable.ToString()); debugString.AppendLine(".limitedUntilTimeStamp = " + this.limitedUntilTimeStamp.ToString()); debugString.AppendLine(".displayMessage = " + this.displayMessage); } return(debugString.ToString()); }
public static ImageRequest DownloadImage(string imageURL) { ImageRequest request = new ImageRequest(); request.isDone = false; UnityWebRequest webRequest = UnityWebRequest.Get(imageURL); webRequest.downloadHandler = new DownloadHandlerTexture(true); var operation = webRequest.SendWebRequest(); operation.completed += (o) => DownloadClient.OnImageDownloadCompleted(operation, request); #if DEBUG if (PluginSettings.data.logAllRequests) { string requestHeaders = ""; List <string> requestKeys = new List <string>(APIClient.UNITY_REQUEST_HEADER_KEYS); requestKeys.AddRange(APIClient.MODIO_REQUEST_HEADER_KEYS); foreach (string headerKey in requestKeys) { string headerValue = webRequest.GetRequestHeader(headerKey); if (headerValue != null) { requestHeaders += "\n" + headerKey + ": " + headerValue; } } int timeStamp = ServerTimeStamp.Now; Debug.Log("IMAGE REQUEST SENT" + "\nTimeStamp: [" + timeStamp.ToString() + "] " + ServerTimeStamp.ToLocalDateTime(timeStamp).ToString() + "\nURL: " + webRequest.url + "\nHeaders: " + requestHeaders); } #endif return(request); }
// ---------[ HELPER FUNCTIONS ]--------- public string ToUnityDebugString() { string debugString = (this.method + " REQUEST FAILED" + "\nResponse received at: [" + this.timeStamp + "] " + ServerTimeStamp.ToLocalDateTime(this.timeStamp) + "\nURL: " + this.url + "\nCode: " + this.responseCode + "\nMessage: " + this.message + "\n"); if (this.fieldValidationMessages != null && this.fieldValidationMessages.Count > 0) { debugString += "Field Validation Messages:\n"; foreach (var kvp in fieldValidationMessages) { debugString += " [" + kvp.Key + "] " + kvp.Value + "\n"; } } return(debugString); }
// ---------[ HELPER FUNCTIONS ]--------- public string ToUnityDebugString() { var debugString = new System.Text.StringBuilder(); string headerString = (this.webRequest == null ? "REQUEST FAILED LOCALLY" : "WEB REQUEST FAILED"); debugString.AppendLine(headerString); if (this.webRequest != null) { debugString.AppendLine("------[ Request Data ]------"); debugString.AppendLine(APIClient.GenerateRequestDebugString(this.webRequest)); debugString.AppendLine("------[ Response Data ]------"); debugString.AppendLine("Time Stamp: " + this.timeStamp + " (" + ServerTimeStamp.ToLocalDateTime(this.timeStamp) + ")"); var responseHeaders = webRequest.GetResponseHeaders(); if (responseHeaders != null && responseHeaders.Count > 0) { debugString.AppendLine("Response Headers:"); foreach (var kvp in responseHeaders) { debugString.AppendLine("- [" + kvp.Key + "] " + kvp.Value); } } debugString.AppendLine("Response Code: " + this.webRequest.responseCode.ToString()); debugString.AppendLine("errorMessage: " + this.errorMessage); if (this.fieldValidationMessages != null && this.fieldValidationMessages.Count > 0) { debugString.AppendLine("Field Validation Messages:"); foreach (var kvp in fieldValidationMessages) { debugString.AppendLine("- [" + kvp.Key + "] " + kvp.Value); } } debugString.AppendLine("isAuthenticationInvalid = " + this.isAuthenticationInvalid.ToString()); debugString.AppendLine("isServerUnreachable = " + this.isServerUnreachable.ToString()); debugString.AppendLine("isRequestUnresolvable = " + this.isRequestUnresolvable.ToString()); debugString.AppendLine("limitedUntilTimeStamp = " + this.limitedUntilTimeStamp.ToString()); debugString.AppendLine("displayMessage = " + this.displayMessage); string contentText = "[NULL]"; if (this.webRequest.downloadHandler != null) { try { contentText = this.webRequest.downloadHandler.text; } catch { contentText = "[NON-TEXT DATA]"; } } } return(debugString.ToString()); }
/// <summary>Tracks and logs a download upon it completing.</summary> public static void DebugDownload(UnityWebRequestAsyncOperation operation, LocalUser userData, string downloadLocation, int timeSent = -1) { #if DEBUG Debug.Assert(operation != null); UnityWebRequest webRequest = operation.webRequest; string userIdString = DebugUtilities.GenerateUserIdString(userData.profile); if (timeSent < 0) { timeSent = ServerTimeStamp.Now; } if (PluginSettings.REQUEST_LOGGING.logOnSend) { var logString = new System.Text.StringBuilder(); logString.AppendLine("[mod.io] Web Request Sent"); logString.Append("URL: "); logString.Append(webRequest.url); logString.Append(" ("); logString.Append(webRequest.method.ToUpper()); logString.AppendLine(")"); if (!string.IsNullOrEmpty(downloadLocation)) { logString.Append("Download Location: "); logString.AppendLine(downloadLocation); } if (timeSent >= 0) { logString.Append("Sent: "); logString.Append(ServerTimeStamp.ToLocalDateTime(timeSent).ToString()); logString.Append(" ["); logString.Append(timeSent.ToString()); logString.AppendLine("]"); } logString.AppendLine(); string requestString = DebugUtilities.GetRequestInfo(webRequest, userIdString); logString.AppendLine("------[ Request ]------"); logString.AppendLine(requestString); Debug.Log(logString.ToString()); } if (PluginSettings.REQUEST_LOGGING.logAllResponses || PluginSettings.REQUEST_LOGGING.errorsAsWarnings) { RequestDebugData debugData = new RequestDebugData() { userIdString = userIdString, timeSent = timeSent, downloadLocation = downloadLocation, }; DebugUtilities.webRequestDebugData.Add(webRequest, debugData); // handle completion if (operation.isDone) { DebugUtilities.OnOperationCompleted(operation); } else { operation.completed += DebugUtilities.OnOperationCompleted; } } #endif // DEBUG }
/// <summary>Callback upon request operation completion.</summary> private static void OnOperationCompleted(AsyncOperation operation) { if (operation == null) { return; } // get vars UnityWebRequestAsyncOperation o = operation as UnityWebRequestAsyncOperation; UnityWebRequest webRequest = o.webRequest; var now = ServerTimeStamp.Now; bool isError = (webRequest.isNetworkError || webRequest.isHttpError); // should we log? if (PluginSettings.REQUEST_LOGGING.logAllResponses || isError) { RequestDebugData debugData; if (!DebugUtilities.webRequestDebugData.TryGetValue(webRequest, out debugData)) { debugData = new RequestDebugData() { userIdString = "NONE_RECORDED", timeSent = -1, downloadLocation = null, }; } // generate strings string requestString = DebugUtilities.GetRequestInfo(webRequest, debugData.userIdString); string responseString = DebugUtilities.GetResponseInfo(webRequest); // generate log string var logString = new System.Text.StringBuilder(); if (!isError) { logString.AppendLine("[mod.io] Web Request Succeeded"); } else { logString.AppendLine("[mod.io] Web Request Failed"); } logString.Append("URL: "); logString.Append(webRequest.url); logString.Append(" ("); logString.Append(webRequest.method.ToUpper()); logString.AppendLine(")"); if (!string.IsNullOrEmpty(debugData.downloadLocation)) { logString.Append("Download Location: "); logString.AppendLine(debugData.downloadLocation); } if (debugData.timeSent >= 0) { logString.Append("Sent: "); logString.Append(ServerTimeStamp.ToLocalDateTime(debugData.timeSent).ToString()); logString.Append(" ["); logString.Append(debugData.timeSent.ToString()); logString.AppendLine("]"); } logString.Append("Completed: "); logString.Append(ServerTimeStamp.ToLocalDateTime(now).ToString()); logString.Append(" ["); logString.Append(now.ToString()); logString.AppendLine("]"); logString.AppendLine(); logString.AppendLine("------[ Request ]------"); logString.AppendLine(requestString); logString.AppendLine("------[ Response ]------"); logString.AppendLine(responseString); // log if (isError && PluginSettings.REQUEST_LOGGING.errorsAsWarnings) { Debug.LogWarning(logString.ToString()); } else { Debug.Log(logString.ToString()); } } DebugUtilities.webRequestDebugData.Remove(webRequest); }
// ---------[ FUNCTIONALITY ]--------- /// <summary>Formats a value as a display string.</summary> public static string FormatValue(object value, Method method, string toStringParameter) { string displayString = string.Empty; if (string.IsNullOrEmpty(toStringParameter)) { // Default value for ToString() in most cases is (G)eneral toStringParameter = "G"; } switch (method) { case Method.ByteCount: { Int64 bytes = 0; if (value != null) { bytes = (Int64)value; } displayString = ValueFormatting.ByteCount(bytes, toStringParameter); } break; case Method.AbbreviatedNumber: { int number = 0; if (value != null) { number = (int)value; } displayString = ValueFormatting.AbbreviateInteger(number, toStringParameter); } break; case Method.TimeStampAsDateTime: { if (value == null) { displayString = "--"; } else { displayString = ServerTimeStamp.ToLocalDateTime((int)value).ToString(toStringParameter); } } break; case Method.Percentage: { if (value == null) { displayString = "--%"; } else { displayString = ((float)value * 100.0f).ToString(toStringParameter) + "%"; } } break; case Method.SecondsAsTime: { int seconds = 0; if (value != null) { seconds = (int)value; } displayString = ValueFormatting.SecondsAsTime(seconds); } break; default: { displayString = null; if (value != null && !string.IsNullOrEmpty(toStringParameter)) { if (value is float) { displayString = ((float)value).ToString(toStringParameter); } else if (value is int) { displayString = ((int)value).ToString(toStringParameter); } else if (value is Int64) { displayString = ((Int64)value).ToString(toStringParameter); } } if (displayString == null) { if (value != null) { displayString = value.ToString(); } else { displayString = string.Empty; } } } break; } return(displayString); }
private static void OnModBinaryRequestCompleted(ModfileIdPair idPair) { FileDownloadInfo downloadInfo = DownloadClient.modfileDownloadMap[idPair]; UnityWebRequest request = downloadInfo.request; bool succeeded = false; downloadInfo.isDone = true; downloadInfo.bytesPerSecond = 0; if (request.isNetworkError || request.isHttpError) { if (request.error.ToUpper() == "USER ABORTED" || request.error.ToUpper() == "REQUEST ABORTED") { #if DEBUG if (PluginSettings.data.logAllRequests) { Debug.Log("DOWNLOAD ABORTED" + "\nDownload aborted at: " + ServerTimeStamp.Now + "\nURL: " + request.url); } #endif downloadInfo.wasAborted = true; } // NOTE(@jackson): This workaround addresses an issue in UnityWebRequests on the // PS4 whereby redirects fail in specific cases. Special thanks to @Eamon of // Spiderling Studios (http://spiderlinggames.co.uk/) #if UNITY_PS4 else if (downloadInfo.error.responseCode == 302) // Redirect limit exceeded { string headerLocation = string.Empty; if (downloadInfo.error.responseHeaders.TryGetValue("location", out headerLocation) && !request.url.Equals(headerLocation)) { if (PluginSettings.data.logAllRequests) { Debug.LogFormat("CAUGHT DOWNLOAD REDIRECTION\nURL: {0}", headerLocation); } downloadInfo.error = null; downloadInfo.isDone = false; DownloadModBinary_Internal(idPair, headerLocation); return; } } #endif else { downloadInfo.error = WebRequestError.GenerateFromWebRequest(request); if (PluginSettings.data.logAllRequests) { WebRequestError.LogAsWarning(downloadInfo.error); } if (modfileDownloadFailed != null) { modfileDownloadFailed(idPair, downloadInfo.error); } } } else { try { if (File.Exists(downloadInfo.target)) { File.Delete(downloadInfo.target); } File.Move(downloadInfo.target + ".download", downloadInfo.target); succeeded = true; } catch (Exception e) { string warningInfo = ("Failed to save mod binary." + "\nFile: " + downloadInfo.target + "\n\n"); Debug.LogWarning("[mod.io] " + warningInfo + Utility.GenerateExceptionDebugString(e)); downloadInfo.error = WebRequestError.GenerateLocal(warningInfo); if (modfileDownloadFailed != null) { modfileDownloadFailed(idPair, downloadInfo.error); } } } if (succeeded) { #if DEBUG if (PluginSettings.data.logAllRequests) { var responseTimeStamp = ServerTimeStamp.Now; Debug.Log("DOWNLOAD SUCEEDED" + "\nDownload completed at: " + ServerTimeStamp.ToLocalDateTime(responseTimeStamp) + "\nURL: " + request.url + "\nFilePath: " + downloadInfo.target); } #endif if (modfileDownloadSucceeded != null) { modfileDownloadSucceeded(idPair, downloadInfo); } } modfileDownloadMap.Remove(idPair); DownloadClient.modfileProgressMarkers.Remove(idPair); }
private static void DownloadModBinary_Internal(ModfileIdPair idPair, string downloadURL) { FileDownloadInfo downloadInfo = modfileDownloadMap[idPair]; downloadInfo.request = UnityWebRequest.Get(downloadURL); string tempFilePath = downloadInfo.target + ".download"; try { Directory.CreateDirectory(Path.GetDirectoryName(tempFilePath)); downloadInfo.request.downloadHandler = new DownloadHandlerFile(tempFilePath); #if PLATFORM_PS4 // NOTE(@jackson): This workaround addresses an issue in UnityWebRequests on the // PS4 whereby redirects fail in specific cases. Special thanks to @Eamon of // Spiderling Studios (http://spiderlinggames.co.uk/) downloadInfo.request.redirectLimit = 0; #endif } catch (Exception e) { string warningInfo = ("Failed to create download file on disk." + "\nFile: " + tempFilePath + "\n\n"); Debug.LogWarning("[mod.io] " + warningInfo + Utility.GenerateExceptionDebugString(e)); if (modfileDownloadFailed != null) { modfileDownloadFailed(idPair, WebRequestError.GenerateLocal(warningInfo)); } return; } var operation = downloadInfo.request.SendWebRequest(); #if DEBUG if (PluginSettings.data.logAllRequests) { string requestHeaders = ""; List <string> requestKeys = new List <string>(APIClient.UNITY_REQUEST_HEADER_KEYS); requestKeys.AddRange(APIClient.MODIO_REQUEST_HEADER_KEYS); foreach (string headerKey in requestKeys) { string headerValue = downloadInfo.request.GetRequestHeader(headerKey); if (headerValue != null) { requestHeaders += "\n" + headerKey + ": " + headerValue; } } int timeStamp = ServerTimeStamp.Now; Debug.Log("DOWNLOAD REQUEST SENT" + "\nTimeStamp: [" + timeStamp.ToString() + "] " + ServerTimeStamp.ToLocalDateTime(timeStamp).ToString() + "\nURL: " + downloadInfo.request.url + "\nHeaders: " + requestHeaders); } #endif operation.completed += (o) => DownloadClient.OnModBinaryRequestCompleted(idPair); DownloadClient.StartMonitoringSpeed(); // notify download started if (DownloadClient.modfileDownloadStarted != null) { DownloadClient.modfileDownloadStarted(idPair, downloadInfo); } }