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 && !req.Post) { 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 (req.Post) { float timeout = Mathf.Max(Constants.Config.Timeout, req.Timeout); PostRequest postReq = new PostRequest(); Runnable.Run(postReq.Send(url, req.Headers)); while (!postReq.IsComplete) { if (req.Cancel) { break; } if ((DateTime.Now - startTime).TotalSeconds > timeout) { break; } yield return(null); } if (req.Cancel) { continue; } resp.Success = postReq.Success; resp.Data = postReq.Data; resp.Error = postReq.Error; resp.HttpResponseCode = postReq.HttpResponseCode; resp.ElapsedTime = (float)(DateTime.Now - startTime).TotalSeconds; resp.Headers = postReq.ResponseHeaders; if (req.OnResponse != null) { req.OnResponse(req, resp); } } 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; }