private IEnumerator ProcessRequestQueue() { // yield AFTER we increment the connection count, so the Send() function can return immediately _activeConnections += 1; #if UNITY_EDITOR if (!UnityEditorInternal.InternalEditorUtility.inBatchMode) { yield return(null); } #else yield return(null); #endif while (_requests.Count > 0) { Request req = _requests.Dequeue(); if (req.Cancel) { continue; } string url = URL; if (!string.IsNullOrEmpty(req.Function)) { url += req.Function; } StringBuilder args = null; foreach (var kp in req.Parameters) { var key = kp.Key; var value = kp.Value; if (value is string) { value = WWW.EscapeURL((string)value); // escape the value } else if (value is byte[]) { value = Convert.ToBase64String((byte[])value); // convert any byte data into base64 string } else if (value is Int32 || value is Int64 || value is UInt32 || value is UInt64 || value is float || value is bool) { value = value.ToString(); } else if (value != null) { Log.Warning("RESTConnector.ProcessRequestQueue()", "Unsupported parameter value type {0}", value.GetType().Name); } else { Log.Error("RESTConnector.ProcessRequestQueue()", "Parameter {0} value is null", key); } if (args == null) { args = new StringBuilder(); } else { args.Append("&"); // append separator } args.Append(key + "=" + value); // append key=value } if (args != null && args.Length > 0) { url += "?" + args.ToString(); } AddHeaders(req.Headers); Response resp = new Response(); DateTime startTime = DateTime.Now; if (!req.Delete) { WWW www = null; if (req.Forms != null) { if (req.Send != null) { Log.Warning("RESTConnector", "Do not use both Send & Form fields in a Request object."); } WWWForm form = new WWWForm(); try { foreach (var formData in req.Forms) { if (formData.Value.IsBinary) { form.AddBinaryData(formData.Key, formData.Value.Contents, formData.Value.FileName, formData.Value.MimeType); } else if (formData.Value.BoxedObject is string) { form.AddField(formData.Key, (string)formData.Value.BoxedObject); } else if (formData.Value.BoxedObject is int) { form.AddField(formData.Key, (int)formData.Value.BoxedObject); } else if (formData.Value.BoxedObject != null) { Log.Warning("RESTConnector.ProcessRequestQueue()", "Unsupported form field type {0}", formData.Value.BoxedObject.GetType().ToString()); } } foreach (var headerData in form.headers) { req.Headers[headerData.Key] = headerData.Value; } } catch (Exception e) { Log.Error("RESTConnector.ProcessRequestQueue()", "Exception when initializing WWWForm: {0}", e.ToString()); } www = new WWW(url, form.data, req.Headers); } else if (req.Send == null) { www = new WWW(url, null, req.Headers); } else { www = new WWW(url, req.Send, req.Headers); } #if ENABLE_DEBUGGING Log.Debug("RESTConnector", "URL: {0}", url); #endif // wait for the request to complete. float timeout = Mathf.Max(Constants.Config.Timeout, req.Timeout); while (!www.isDone) { if (req.Cancel) { break; } if ((DateTime.Now - startTime).TotalSeconds > timeout) { break; } if (req.OnUploadProgress != null) { req.OnUploadProgress(www.uploadProgress); } if (req.OnDownloadProgress != null) { req.OnDownloadProgress(www.progress); } #if UNITY_EDITOR if (!UnityEditorInternal.InternalEditorUtility.inBatchMode) { yield return(null); } #else yield return(null); #endif } if (req.Cancel) { continue; } bool bError = false; Error error = null; if (!string.IsNullOrEmpty(www.error)) { long nErrorCode = -1; int nSeperator = www.error.IndexOf(' '); if (nSeperator > 0 && long.TryParse(www.error.Substring(0, nSeperator).Trim(), out nErrorCode)) { switch (nErrorCode) { case HTTP_STATUS_OK: case HTTP_STATUS_CREATED: case HTTP_STATUS_ACCEPTED: bError = false; break; default: bError = true; break; } } else { bError = true; } error = new Error() { URL = url, ErrorCode = resp.HttpResponseCode = nErrorCode, ErrorMessage = www.error, Response = www.text, ResponseHeaders = www.responseHeaders }; if (bError) { Log.Error("RESTConnector.ProcessRequestQueue()", "URL: {0}, ErrorCode: {1}, Error: {2}, Response: {3}", url, nErrorCode, www.error, string.IsNullOrEmpty(www.text) ? "" : www.text); } else { Log.Warning("RESTConnector.ProcessRequestQueue()", "URL: {0}, ErrorCode: {1}, Error: {2}, Response: {3}", url, nErrorCode, www.error, string.IsNullOrEmpty(www.text) ? "" : www.text); } } if (!www.isDone) { Log.Error("RESTConnector.ProcessRequestQueue()", "Request timed out for URL: {0}", url); bError = true; } /*if (!bError && (www.bytes == null || www.bytes.Length == 0)) * { * Log.Warning("RESTConnector.ProcessRequestQueue()", "No data recevied for URL: {0}", url); * bError = true; * }*/ // generate the Response object now.. if (!bError) { resp.Success = true; resp.Data = www.bytes; resp.HttpResponseCode = GetResponseCode(www); } else { resp.Success = false; resp.Error = error; } resp.Headers = www.responseHeaders; resp.ElapsedTime = (float)(DateTime.Now - startTime).TotalSeconds; // if the response is over a threshold, then log with status instead of debug if (resp.ElapsedTime > LogResponseTime) { Log.Warning("RESTConnector.ProcessRequestQueue()", "Request {0} completed in {1} seconds.", url, resp.ElapsedTime); } if (req.OnResponse != null) { req.OnResponse(req, resp); } www.Dispose(); } else { #if ENABLE_DEBUGGING Log.Debug("RESTConnector.ProcessRequestQueue90", "Delete Request URL: {0}", url); #endif float timeout = Mathf.Max(Constants.Config.Timeout, req.Timeout); DeleteRequest deleteReq = new DeleteRequest(); Runnable.Run(deleteReq.Send(url, req.Headers)); while (!deleteReq.IsComplete) { if (req.Cancel) { break; } if ((DateTime.Now - startTime).TotalSeconds > timeout) { break; } yield return(null); } if (req.Cancel) { continue; } resp.Success = deleteReq.Success; resp.Data = deleteReq.Data; resp.Error = deleteReq.Error; resp.HttpResponseCode = deleteReq.HttpResponseCode; resp.ElapsedTime = (float)(DateTime.Now - startTime).TotalSeconds; resp.Headers = deleteReq.ResponseHeaders; if (req.OnResponse != null) { req.OnResponse(req, resp); } } } // reduce the connection count before we exit.. _activeConnections -= 1; yield break; }
private IEnumerator ProcessRequestQueue() { // yield AFTER we increment the connection count, so the Send() function can return immediately m_ActiveConnections += 1; yield return(null); while (m_Requests.Count > 0) { Request req = m_Requests.Dequeue(); if (req.Cancel) { continue; } string url = URL; if (!string.IsNullOrEmpty(req.Function)) { url += req.Function; } StringBuilder args = null; foreach (var kp in req.Parameters) { var key = kp.Key; var value = kp.Value; if (value is string) { value = WWW.EscapeURL((string)value); // escape the value } else if (value is byte[]) { value = Convert.ToBase64String((byte[])value); // convert any byte data into base64 string } else if (value is Int32 || value is Int64 || value is UInt32 || value is UInt64) { value = value.ToString(); } else if (value != null) { Log.Warning("RESTConnector", "Unsupported parameter value type {0}", value.GetType().Name); } else { Log.Error("RESTConnector", "Parameter {0} value is null", key); } if (args == null) { args = new StringBuilder(); } else { args.Append("&"); // append separator } args.Append(key + "=" + value); // append key=value } if (args != null && args.Length > 0) { url += "?" + args.ToString(); } AddHeaders(req.Headers); Response resp = new Response(); DateTime startTime = DateTime.Now; if (!req.Delete) { WWW www = null; if (req.Forms != null) { if (req.Send != null) { Log.Warning("RESTConnector", "Do not use both Send & Form fields in a Request object."); } WWWForm form = new WWWForm(); try { foreach (var kp in req.Forms) { if (kp.Value.IsBinary) { form.AddBinaryData(kp.Key, kp.Value.Contents, kp.Value.FileName, kp.Value.MimeType); } else if (kp.Value.BoxedObject is string) { form.AddField(kp.Key, (string)kp.Value.BoxedObject); } else if (kp.Value.BoxedObject is int) { form.AddField(kp.Key, (int)kp.Value.BoxedObject); } else if (kp.Value.BoxedObject != null) { Log.Warning("RESTCOnnector", "Unsupported form field type {0}", kp.Value.BoxedObject.GetType().ToString()); } } foreach (var kp in form.headers) { req.Headers[kp.Key] = kp.Value; } } catch (Exception e) { Log.Error("RESTConnector", "Exception when initializing WWWForm: {0}", e.ToString()); } www = new WWW(url, form.data, req.Headers); } else if (req.Send == null) { www = new WWW(url, null, req.Headers); } else { www = new WWW(url, req.Send, req.Headers); } #if ENABLE_DEBUGGING Log.Debug("RESTCOnnector", "URL: {0}", url); #endif // wait for the request to complete. float timeout = Mathf.Max(Config.Instance.TimeOut, req.Timeout); while (!www.isDone) { if (req.Cancel) { break; } if ((DateTime.Now - startTime).TotalSeconds > timeout) { break; } if (req.OnUploadProgress != null) { req.OnUploadProgress(www.uploadProgress); } if (req.OnDownloadProgress != null) { req.OnDownloadProgress(www.progress); } yield return(null); } if (req.Cancel) { continue; } bool bError = false; if (!string.IsNullOrEmpty(www.error)) { int nErrorCode = -1; int nSeperator = www.error.IndexOf(' '); if (nSeperator > 0 && int.TryParse(www.error.Substring(0, nSeperator).Trim(), out nErrorCode)) { bError = nErrorCode != 200; } if (bError) { Log.Error("RESTConnector", "URL: {0}, ErrorCode: {1}, Error: {2}, Response: {3}", url, nErrorCode, www.error, string.IsNullOrEmpty(www.text) ? "" : www.text); } else { Log.Warning("RESTConnector", "URL: {0}, ErrorCode: {1}, Error: {2}, Response: {3}", url, nErrorCode, www.error, string.IsNullOrEmpty(www.text) ? "" : www.text); } } if (!www.isDone) { Log.Error("RESTConnector", "Request timed out for URL: {0}", url); bError = true; } if (!bError && (www.bytes == null || www.bytes.Length == 0)) { Log.Warning("RESTConnector", "No data recevied for URL: {0}", url); bError = true; } // generate the Response object now.. if (!bError) { resp.Success = true; resp.Data = www.bytes; } else { resp.Success = false; resp.Error = string.Format("Request Error.\nURL: {0}\nError: {1}", url, string.IsNullOrEmpty(www.error) ? "Timeout" : www.error); } resp.ElapsedTime = (float)(DateTime.Now - startTime).TotalSeconds; // if the response is over a threshold, then log with status instead of debug if (resp.ElapsedTime > LogResponseTime) { Log.Warning("RESTConnector", "Request {0} completed in {1} seconds.", url, resp.ElapsedTime); } if (req.OnResponse != null) { req.OnResponse(req, resp); } www.Dispose(); } else { #if UNITY_EDITOR float timeout = Mathf.Max(Config.Instance.TimeOut, req.Timeout); DeleteRequest deleteReq = new DeleteRequest(); deleteReq.Send(url, req.Headers); while (!deleteReq.IsComplete) { if (req.Cancel) { break; } if ((DateTime.Now - startTime).TotalSeconds > timeout) { break; } yield return(null); } if (req.Cancel) { continue; } resp.Success = deleteReq.Success; #else Log.Warning("RESTConnector", "DELETE method is supported in the editor only."); resp.Success = false; #endif resp.ElapsedTime = (float)(DateTime.Now - startTime).TotalSeconds; if (req.OnResponse != null) { req.OnResponse(req, resp); } } } // reduce the connection count before we exit.. m_ActiveConnections -= 1; yield break; }