T IRequestExecutor.DoSyncApiCall <T>(IRestRequest request, RequestType requestType, int authTry = 0)
        {
            IRestClient client = new RestClient(_client.ServerUri)
            {
                UserAgent = DracoonClient.HttpConfig.UserAgent,
            };

            if (DracoonClient.HttpConfig.WebProxy != null)
            {
                client.Proxy = DracoonClient.HttpConfig.WebProxy;
            }

            IRestResponse response = client.Execute(request);

            if (response.ErrorException is WebException we)
            {
                // It's an HTTP exception
                DracoonErrorParser.ParseError(we, requestType);
            }

            if (!response.IsSuccessful)
            {
                // It's an API exception
                if (RequestIsOAuthRequest(requestType))
                {
                    OAuthErrorParser.ParseError(response, requestType);
                }

                try {
                    DracoonErrorParser.ParseError(response, requestType);
                } catch (DracoonApiException apiError) {
                    if (apiError.ErrorCode == DracoonApiCode.AUTH_UNAUTHORIZED && authTry < 3)
                    {
                        DracoonClient.Log.Debug(Logtag, "Retry the refresh of the access token in " + authTry * 1000 + " millis again.");
                        Thread.Sleep(1000 * authTry);
                        _auth.RefreshAccessToken();
                        foreach (Parameter cur in request.Parameters)
                        {
                            if (cur.Name == ApiConfig.AuthorizationHeader)
                            {
                                cur.Value = _auth.BuildAuthString();
                            }
                        }

                        return(((IRequestExecutor)this).DoSyncApiCall <T>(request, requestType, authTry + 1));
                    }

                    throw apiError;
                }
            }

            if (typeof(T) == typeof(VoidResponse))
            {
                return(new VoidResponse() as T);
            }

            return(JsonConvert.DeserializeObject <T>(response.Content));
        }
        byte[] IRequestExecutor.ExecuteWebClientDownload(WebClient requestClient, Uri target, RequestType type, Thread asyncThread = null,
                                                         int sendTry = 0)
        {
            byte[] response = null;
            try {
                Task <byte[]> responseTask = requestClient.DownloadDataTaskAsync(target);
                response = responseTask.Result;
            } catch (AggregateException ae) {
                if (ae.InnerException is WebException we)
                {
                    if (we.Status == WebExceptionStatus.SecureChannelFailure)
                    {
                        const string message = "Server SSL handshake failed!";
                        DracoonClient.Log.Error(Logtag, message, we);
                        throw new DracoonNetInsecureException(message, we);
                    }

                    if (we.Status == WebExceptionStatus.RequestCanceled)
                    {
                        throw new ThreadInterruptedException();
                    }

                    if (we.Status == WebExceptionStatus.ProtocolError)
                    {
                        DracoonErrorParser.ParseError(we, type);
                    }
                    else
                    {
                        string message = "Server communication failed!";
                        DracoonClient.Log.Debug(Logtag, message);
                        if (DracoonClient.HttpConfig.RetryEnabled && sendTry < 3)
                        {
                            DracoonClient.Log.Debug(Logtag, "Retry the request in " + sendTry * 1000 + " millis again.");
                            Thread.Sleep(1000 * sendTry);
                            return(((IRequestExecutor)this).ExecuteWebClientDownload(requestClient, target, type, asyncThread, sendTry + 1));
                        }
                        else
                        {
                            if (asyncThread != null && asyncThread.ThreadState == ThreadState.Aborted)
                            {
                                throw new ThreadInterruptedException();
                            }

                            DracoonErrorParser.ParseError(we, type);
                        }
                    }
                }
            }

            return(response);
        }
        protected ApiNode S3Finished()
        {
            int       currentInterval = 500;
            Stopwatch s3Polling       = Stopwatch.StartNew();

            while (true)
            {
                if (s3Polling.ElapsedMilliseconds >= currentInterval)
                {
                    IRestRequest request = Client.Builder.GetS3Status(UploadToken.UploadId);
                    ApiS3Status  status  = Client.Executor.DoSyncApiCall <ApiS3Status>(request, RequestType.GetS3Status);
                    switch (status.Status)
                    {
                    case "done":
                        s3Polling.Stop();
                        return(status.Node);

                    case "transfer":
                        break;

                    case "finishing":
                        break;

                    case "error":
                        s3Polling.Stop();
                        DracoonErrorParser.ParseError(status.ErrorInfo, RequestType.GetS3Status);
                        goto default;

                    default:
                        s3Polling.Stop();
                        throw new DracoonApiException(DracoonApiCode.SERVER_S3_UPLOAD_COMPLETION_FAILED);
                    }

                    if (currentInterval < MAX_S3_POLLING_INTERVAL)
                    {
                        currentInterval *= 2;
                    }

                    s3Polling.Restart();
                }
            }
        }
        public byte[] ExecuteWebClientChunkUpload(WebClient requestClient, Uri target, byte[] data, RequestType type, Thread asyncThread = null,
                                                  int sendTry = 0)
        {
            byte[] response = null;
            try {
                string method = "POST";
                if (type == RequestType.PutUploadS3Chunk)
                {
                    method = "PUT";
                }

                Task <byte[]> responseTask = requestClient.UploadDataTaskAsync(target, method, data);
                if (type == RequestType.PutUploadS3Chunk)
                {
                    responseTask.Wait();
                    for (int i = 0; i < requestClient.ResponseHeaders.Count; i++)
                    {
                        if (requestClient.ResponseHeaders.GetKey(i).ToLower().Equals("etag"))
                        {
                            string eTag = requestClient.ResponseHeaders.Get(i);
                            eTag     = eTag.Replace("\"", "").Replace("\\", "").Replace("/", "");
                            response = ApiConfig.ENCODING.GetBytes(eTag);
                        }
                    }
                }
                else
                {
                    response = responseTask.Result;
                }
            } catch (AggregateException ae) {
                if (ae.InnerException is WebException we)
                {
                    if (we.Status == WebExceptionStatus.SecureChannelFailure)
                    {
                        string message = "Server SSL handshake failed!";
                        DracoonClient.Log.Error(Logtag, message, we);
                        throw new DracoonNetInsecureException(message, we);
                    }

                    if (we.Status == WebExceptionStatus.RequestCanceled)
                    {
                        throw new ThreadInterruptedException();
                    }

                    if (we.Status == WebExceptionStatus.ProtocolError)
                    {
                        DracoonErrorParser.ParseError(we, type);
                    }
                    else
                    {
                        string message = "Server communication failed!";
                        DracoonClient.Log.Debug(Logtag, message);
                        if (DracoonClient.HttpConfig.RetryEnabled && sendTry < 3)
                        {
                            DracoonClient.Log.Debug(Logtag, "Retry the request in " + sendTry * 1000 + " millis again.");
                            Thread.Sleep(1000 * sendTry);
                            return(((IRequestExecutor)this).ExecuteWebClientChunkUpload(requestClient, target, data, type, asyncThread, sendTry + 1));
                        }
                        else
                        {
                            if (asyncThread != null && asyncThread.ThreadState == ThreadState.Aborted)
                            {
                                throw new ThreadInterruptedException();
                            }

                            DracoonErrorParser.ParseError(we, type);
                        }
                    }
                }
            }

            return(response);
        }