예제 #1
0
        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;
        }