private string RequestJsonStringWithRetry(
            Uri uri,
            RouteStyle routeStyle,
            string httpMethod,
            string requestArg = "",
            Stream body       = null)
        {
            var attempt    = 0;
            var maxRetries = this.YfyClientConfig.HttpConfig.MaxRetries;
            var r          = new Random();

            if (routeStyle == RouteStyle.Upload)
            {
                if (body == null)
                {
                    throw new ArgumentNullException(nameof(body));
                }

                //为了重试机制,上传的流必须可以检索,否则无法重试
                if (!body.CanSeek)
                {
                    maxRetries = 0;
                }
            }

            while (true)
            {
                try
                {
                    return(this.RequestJsonString(uri, routeStyle, httpMethod, requestArg, body));
                }
                catch (RateLimitException)
                {
                    throw;
                }
                catch (RetryException re)
                {
                    if (++attempt > maxRetries)
                    {
                        throw new InternalServerException(re);
                    }
                }
                catch (TokenRefreshedException)
                {
                }

                var backoff = TimeSpan.FromSeconds(Math.Pow(2, attempt) * r.NextDouble());
                Thread.Sleep(backoff);

                if (body != null)
                {
                    body.Position = 0;
                }
            }
        }
        /// <summary>
        /// The add new panel.
        /// </summary>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <param name="description">
        /// The description.
        /// </param>
        /// <param name="panelType">
        /// The panel type.
        /// </param>
        /// <param name="logoImagePath">
        /// The logo image path.
        /// </param>
        /// <param name="backGroundImagePath">
        /// The back ground image path.
        /// </param>
        /// <returns>
        /// The <see cref="PanelRootObject"/>.
        /// </returns>
        public PanelRootObject AddPanel(
            string name,
            string description,
            PanelType panelType,
            string logoImagePath       = "",
            string backGroundImagePath = "")
        {
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(description))
            {
                return(_result.ErrorToObject(new PanelRootObject(), "Invalid parameter(s)"));
            }

            string     files      = string.Empty;
            RouteStyle routeStyle = RouteStyle.Rpc;

            if (!string.IsNullOrEmpty(logoImagePath))
            {
                if (!File.Exists(logoImagePath))
                {
                    return(_result.ErrorToObject(new PanelRootObject(), "File not exist!"));
                }

                routeStyle = RouteStyle.Upload;
                var logoimage = Helper.MoveFile(logoImagePath, "Panel-logo"); // File name must contains 'logo' keyword.
                files = logoimage + ";";
            }

            if (!string.IsNullOrEmpty(backGroundImagePath))
            {
                if (!File.Exists(backGroundImagePath))
                {
                    return(_result.ErrorToObject(new PanelRootObject(), "File not exist!"));
                }

                routeStyle = RouteStyle.Upload;
                var bkgImage = Helper.MoveFile(
                    backGroundImagePath,
                    "Panel-background"); // File name must contains 'background' keyword.
                files = files + bkgImage;
            }

            Task <Result> x = RequestHandler.SendRequestAsync(
                string.Empty,
                "api/UserPanel/AddPanel?Name=" + name + "&Description=" + description + "&panelType="
                + (Int32)panelType,
                HttpMethod.Post,
                routeStyle,
                string.IsNullOrEmpty(files) ? null : files);

            x.Wait();
            return(x.Result.JsonToObject(new PanelRootObject(), "Panels"));
        }
Esempio n. 3
0
        /// <summary>
        /// Requests the JSON string.
        /// </summary>
        /// <param name="host">The host.</param>
        /// <param name="routeName">Name of the route.</param>
        /// <param name="auth">The auth type of the route.</param>
        /// <param name="routeStyle">The route style.</param>
        /// <param name="requestArg">The request argument.</param>
        /// <param name="body">The body to upload if <paramref name="routeStyle"/>
        /// is <see cref="RouteStyle.Upload"/>.</param>
        /// <returns>The asynchronous task with the result.</returns>
        private async Task <Result> RequestJsonString(
            string host,
            string routeName,
            string auth,
            RouteStyle routeStyle,
            string requestArg,
            Stream body = null)
        {
            var hostname = this.options.HostMap[host];
            var uri      = this.GetRouteUri(hostname, routeName);

            var request = new HttpRequestMessage(HttpMethod.Post, uri);

            if (auth == AuthType.User || auth == AuthType.Team)
            {
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", this.options.OAuth2AccessToken);
            }
            else if (auth == AuthType.App)
            {
                request.Headers.Authorization = new AuthenticationHeaderValue("Basic", this.options.OAuth2AccessToken);
            }
            else if (auth == AuthType.NoAuth)
            {
            }
            else
            {
                throw new ArgumentException("Invalid auth type", auth);
            }

            request.Headers.TryAddWithoutValidation("User-Agent", this.options.UserAgent);

            if (this.selectUser != null)
            {
                request.Headers.TryAddWithoutValidation("Dropbox-Api-Select-User", this.selectUser);
            }

            if (this.selectAdmin != null)
            {
                request.Headers.TryAddWithoutValidation("Dropbox-Api-Select-Admin", this.selectAdmin);
            }

            var completionOption = HttpCompletionOption.ResponseContentRead;

            switch (routeStyle)
            {
            case RouteStyle.Rpc:
                request.Content = new StringContent(requestArg, Encoding.UTF8, "application/json");
                break;

            case RouteStyle.Download:
                request.Headers.Add(DropboxApiArgHeader, requestArg);

                // This is required to force libcurl remove default content type header.
                request.Content = new StringContent("");
                request.Content.Headers.ContentType = null;

                completionOption = HttpCompletionOption.ResponseHeadersRead;
                break;

            case RouteStyle.Upload:
                request.Headers.Add(DropboxApiArgHeader, requestArg);
                if (body == null)
                {
                    throw new ArgumentNullException("body");
                }

                request.Content = new CustomStreamContent(body);
                request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                break;

            default:
                throw new InvalidOperationException(string.Format(
                                                        CultureInfo.InvariantCulture,
                                                        "Unknown route style: {0}",
                                                        routeStyle));
            }

            var disposeResponse = true;
            var response        = await this.getHttpClient(host).SendAsync(request, completionOption).ConfigureAwait(false);

            var requestId = GetRequestId(response);

            try
            {
                if ((int)response.StatusCode >= 500)
                {
                    var text = await response.Content.ReadAsStringAsync();

                    text = this.CheckForError(text);
                    throw new RetryException(requestId, (int)response.StatusCode, message: text, uri: uri);
                }
                else if (response.StatusCode == HttpStatusCode.BadRequest)
                {
                    var text = await response.Content.ReadAsStringAsync();

                    text = this.CheckForError(text);
                    throw new BadInputException(requestId, text, uri);
                }
                else if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    throw AuthException.Decode(reason, () => new AuthException(GetRequestId(response)));
                }
                else if ((int)response.StatusCode == 429)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    throw RateLimitException.Decode(reason, () => new RateLimitException(GetRequestId(response)));
                }
                else if (response.StatusCode == HttpStatusCode.Forbidden)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    throw AccessException.Decode(reason, () => new AccessException(GetRequestId(response)));
                }
                else if (response.StatusCode == HttpStatusCode.Conflict ||
                         response.StatusCode == HttpStatusCode.NotFound)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    return(new Result
                    {
                        IsError = true,
                        ObjectResult = reason,
                        RequestId = GetRequestId(response)
                    });
                }
                else if ((int)response.StatusCode >= 200 && (int)response.StatusCode <= 299)
                {
                    if (routeStyle == RouteStyle.Download)
                    {
                        disposeResponse = false;
                        return(new Result
                        {
                            IsError = false,
                            ObjectResult = response.Headers.GetValues(DropboxApiResultHeader).FirstOrDefault(),
                            HttpResponse = response
                        });
                    }
                    else
                    {
                        return(new Result
                        {
                            IsError = false,
                            ObjectResult = await response.Content.ReadAsStringAsync()
                        });
                    }
                }
                else
                {
                    var text = await response.Content.ReadAsStringAsync();

                    text = this.CheckForError(text);
                    throw new HttpException(requestId, (int)response.StatusCode, text, uri);
                }
            }
            finally
            {
                if (disposeResponse)
                {
                    response.Dispose();
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Requests the JSON string with retry.
        /// </summary>
        /// <param name="host">The host.</param>
        /// <param name="auth">The auth type of the route.</param>
        /// <param name="routeName">Name of the route.</param>
        /// <param name="routeStyle">The route style.</param>
        /// <param name="requestArg">The request argument.</param>
        /// <param name="body">The body to upload if <paramref name="routeStyle"/>
        /// is <see cref="RouteStyle.Upload"/>.</param>
        /// <returns>The asynchronous task with the result.</returns>
        private async Task <Result> RequestJsonStringWithRetry(
            string host,
            string routeName,
            string auth,
            RouteStyle routeStyle,
            string requestArg,
            Stream body = null)
        {
            var attempt    = 0;
            var maxRetries = this.options.MaxClientRetries;
            var r          = new Random();

            if (routeStyle == RouteStyle.Upload)
            {
                if (body == null)
                {
                    throw new ArgumentNullException("body");
                }

                // to support retry logic, the body stream must be seekable
                // if it isn't we won't retry
                if (!body.CanSeek)
                {
                    maxRetries = 0;
                }
            }

            try
            {
                while (true)
                {
                    try
                    {
                        return(await this.RequestJsonString(host, routeName, auth, routeStyle, requestArg, body)
                               .ConfigureAwait(false));
                    }
                    catch (RateLimitException)
                    {
                        throw;
                    }
                    catch (RetryException)
                    {
                        // dropbox maps 503 - ServiceUnavailable to be a rate limiting error.
                        // do not count a rate limiting error as an attempt
                        if (++attempt > maxRetries)
                        {
                            throw;
                        }
                    }

                    // use exponential backoff
                    var backoff = TimeSpan.FromSeconds(Math.Pow(2, attempt) * r.NextDouble());
#if PORTABLE40
                    await TaskEx.Delay(backoff);
#else
                    await Task.Delay(backoff);
#endif
                    if (body != null)
                    {
                        body.Position = 0;
                    }
                }
            }
            finally
            {
                if (body != null)
                {
                    body.Dispose();
                }
            }
        }
        /// <summary>
        /// Requests the JSON string with retry.
        /// </summary>
        /// <param name="host">The host.</param>
        /// <param name="auth">The auth type of the route.</param>
        /// <param name="routeName">Name of the route.</param>
        /// <param name="routeStyle">The route style.</param>
        /// <param name="requestArg">The request argument.</param>
        /// <param name="body">The body to upload if <paramref name="routeStyle"/>
        /// is <see cref="RouteStyle.Upload"/>.</param>
        /// <returns>The asynchronous task with the result.</returns>
        private async Task <Result> RequestJsonStringWithRetry(
            string host,
            string routeName,
            string auth,
            RouteStyle routeStyle,
            string requestArg,
            Stream body = null)
        {
            var attempt    = 0;
            var maxRetries = this.options.MaxClientRetries;
            var r          = new Random();

            byte[] cachedBody        = null;
            long   cachedStreamStart = 0;

            if (routeStyle == RouteStyle.Upload)
            {
                // to support retry logic, the body stream must be seekable
                // if it isn't we won't retry
                if (!body.CanSeek)
                {
                    maxRetries = 0;
                }
                else if (body is MemoryStream)
                {
                    cachedStreamStart = body.Position;
                    cachedBody        = ((MemoryStream)body).ToArray();
                }
                else
                {
                    cachedStreamStart = body.Position;
                    using (var mem = new MemoryStream())
                    {
                        await body.CopyToAsync(mem).ConfigureAwait(false);

                        cachedBody = mem.ToArray();
                    }
                }
            }

            while (true)
            {
                try
                {
                    if (cachedBody == null)
                    {
                        return(await this.RequestJsonString(host, routeName, auth, routeStyle, requestArg, body)
                               .ConfigureAwait(false));
                    }
                    else
                    {
                        using (var mem = new MemoryStream(cachedBody, writable: false))
                        {
                            mem.Position = cachedStreamStart;
                            return(await this.RequestJsonString(host, routeName, auth, routeStyle, requestArg, mem)
                                   .ConfigureAwait(false));
                        }
                    }
                }
                catch (RateLimitException)
                {
                    throw;
                }
                catch (RetryException)
                {
                    // dropbox maps 503 - ServiceUnavailable to be a rate limiting error.
                    // do not count a rate limiting error as an attempt
                    if (++attempt > maxRetries)
                    {
                        throw;
                    }
                }

                // use exponential backoff
                var backoff = TimeSpan.FromSeconds(Math.Pow(2, attempt) * r.NextDouble());
#if PORTABLE40
                await TaskEx.Delay(backoff);
#else
                await Task.Delay(backoff);
#endif
            }
        }
        /// <summary>
        /// The send api request async for calling route method.
        /// </summary>
        /// <param name="host">
        /// The host.
        /// </param>
        /// <param name="routeName">
        /// The route name.
        /// </param>
        /// <param name="method">
        /// The method.
        /// </param>
        /// <param name="routeStyle">
        /// The route style.
        /// </param>
        /// <param name="requestArg">
        /// The request arg.
        /// </param>
        /// <param name="body">
        /// The body.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// </exception>
        public async Task <Result> SendRequestAsync(
            string host,
            string routeName,
            HttpMethod method,
            RouteStyle routeStyle,
            string requestArg,
            Stream body = null)
        {
            var uri = new Uri(Hostname + routeName);

            var request = new HttpRequestMessage(method, uri);

            if (!string.IsNullOrEmpty(SessionId))
            {
                request.Headers.Add("SessionID", SessionId);
            }

            switch (routeStyle)
            {
            case RouteStyle.Rpc:
                if ((method == HttpMethod.Post || method == HttpMethod.Put || method == HttpMethod.Delete) &&
                    requestArg != null)
                {
                    request.Content = new StringContent(requestArg, Encoding.UTF8, "application/json");
                }
                break;

            case RouteStyle.Download:
                if (method == HttpMethod.Post)
                {
                    request.Content = new StringContent(requestArg, Encoding.UTF8, "application/json");
                }
                break;

            case RouteStyle.Upload:
                MultipartFormDataContent multiPartContent = new MultipartFormDataContent("----MyGreatBoundary");
                char[] charSeparators = new[] { ';' };
                var    files          = requestArg.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries);
                foreach (var file in files)
                {
                    var byteArrayContent = CreateFileContent(file, out string filename);
                    multiPartContent.Add(byteArrayContent, filename, filename);
                }

                request.Content = multiPartContent;
                break;

            default:
                throw new InvalidOperationException(
                          string.Format(CultureInfo.InvariantCulture, "Unknown route style: {0}", routeStyle));
            }

            var disposeResponse = true;
            var response        = await HttpClient.SendAsync(request).ConfigureAwait(false);

            try
            {
                if ((int)response.StatusCode >= 500)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    reason = CheckForError(reason);
                    return(new Result {
                        IsError = true, ObjectResult = reason, HttpResponse = response
                    });
                }
                else if (response.StatusCode == HttpStatusCode.BadRequest)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    reason = CheckForError(reason);
                    return(new Result {
                        IsError = true, ObjectResult = reason, HttpResponse = response
                    });
                }
                else if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    reason = CheckForError(reason);
                    return(new Result {
                        IsError = true, ObjectResult = reason, HttpResponse = response
                    });
                }
                else if ((int)response.StatusCode == 429)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    reason = CheckForError(reason);
                    return(new Result {
                        IsError = true, ObjectResult = reason, HttpResponse = response
                    });
                }
                else if (response.StatusCode == HttpStatusCode.Conflict ||
                         response.StatusCode == HttpStatusCode.Forbidden ||
                         response.StatusCode == HttpStatusCode.NotFound)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    reason = CheckForError(reason);
                    return(new Result {
                        IsError = true, ObjectResult = reason, HttpResponse = response
                    });
                }
                else if ((int)response.StatusCode >= 200 && (int)response.StatusCode <= 299)
                {
                    if (routeStyle == RouteStyle.Download)
                    {
                        disposeResponse = false;
                        return(new Result
                        {
                            IsError = false,
                            ObjectResult = await response.Content.ReadAsStringAsync(),
                            HttpResponse = response
                        });
                    }
                    else
                    {
                        return(new Result
                        {
                            IsError = false,
                            ObjectResult = await response.Content.ReadAsStringAsync(),
                            HttpResponse = response
                        });
                    }
                }
                else
                {
                    var text = await response.Content.ReadAsStringAsync();

                    CheckForError(text);
                    return(new Result
                    {
                        IsError = true,
                        ObjectResult = await response.Content.ReadAsStringAsync(),
                        HttpResponse = response
                    });
                }
            }
            finally
            {
                if (disposeResponse)
                {
                    response.Dispose();
                }
            }
        }
        /// <summary>
        /// Requests the JSON string.
        /// </summary>
        /// <param name="host">The host.</param>
        /// <param name="routeName">Name of the route.</param>
        /// <param name="routeStyle">The route style.</param>
        /// <param name="requestArg">The request argument.</param>
        /// <param name="body">The body to upload if <paramref name="routeStyle"/>
        /// is <see cref="RouteStyle.Upload"/>.</param>
        /// <returns>The asynchronous task with the result.</returns>
        private async Task <Result> RequestJsonString(
            string host,
            string routeName,
            RouteStyle routeStyle,
            string requestArg,
            Stream body = null)
        {
            var hostname = this.hostMap[host];
            var uri      = this.GetRouteUri(hostname, routeName);

            var request = new HttpRequestMessage(HttpMethod.Post, uri);

            switch (routeStyle)
            {
            case RouteStyle.Rpc:
                request.Content = new StringContent(requestArg, Encoding.UTF8, "application/json");
                break;

            case RouteStyle.Download:
                request.Headers.Add(DropboxApiArgHeader, requestArg);
                break;

            case RouteStyle.Upload:
                request.Headers.Add(DropboxApiArgHeader, requestArg);
                if (body == null)
                {
                    throw new ArgumentNullException("body");
                }
                request.Content = new StreamContent(body);
                request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                break;

            default:
                throw new InvalidOperationException(string.Format(
                                                        CultureInfo.InvariantCulture,
                                                        "Unknown route style: {0}",
                                                        routeStyle));
            }

            var disposeResponse = true;
            var response        = await this.httpClient.SendAsync(request);

            try
            {
                if ((int)response.StatusCode >= 500)
                {
                    var text = await response.Content.ReadAsStringAsync();

                    text = this.CheckForError(text);
                    throw new RetryException((int)response.StatusCode, message: text, uri: uri);
                }
                else if (response.StatusCode == HttpStatusCode.BadRequest)
                {
                    var text = await response.Content.ReadAsStringAsync();

                    text = this.CheckForError(text);
                    throw new BadInputException(text, uri);
                }
                else if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    var text = await response.Content.ReadAsStringAsync();

                    text = this.CheckForError(text);
                    throw new AuthException(text, uri);
                }
                else if ((int)response.StatusCode == 429)
                {
                    throw new RetryException(429, uri: uri, isRateLimit: true);
                }
                else if (response.StatusCode == HttpStatusCode.Conflict ||
                         response.StatusCode == HttpStatusCode.Forbidden ||
                         response.StatusCode == HttpStatusCode.NotFound)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    return(new Result
                    {
                        IsError = true,
                        ObjectResult = reason
                    });
                }
                else if ((int)response.StatusCode >= 200 && (int)response.StatusCode <= 299)
                {
                    if (routeStyle == RouteStyle.Download)
                    {
                        disposeResponse = false;
                        return(new Result
                        {
                            IsError = false,
                            ObjectResult = response.Headers.GetValues(DropboxApiResultHeader).FirstOrDefault(),
                            HttpResponse = response
                        });
                    }
                    else
                    {
                        return(new Result
                        {
                            IsError = false,
                            ObjectResult = await response.Content.ReadAsStringAsync()
                        });
                    }
                }
                else
                {
                    var text = await response.Content.ReadAsStringAsync();

                    text = this.CheckForError(text);
                    throw new HttpException((int)response.StatusCode, text, uri);
                }
            }
            finally
            {
                if (disposeResponse)
                {
                    response.Dispose();
                }
            }
        }
        private string RequestJsonString(
            Uri uri,
            RouteStyle routeStyle,
            string httpMethod,
            string requestArg = "",
            Stream body       = null)
        {
            HttpWebRequest  request = WebRequest.Create(uri) as HttpWebRequest;
            HttpWebResponse response;

            request.Method  = httpMethod;
            request.Timeout = YfyClientConfig.HttpConfig.Timeout;

            request.Headers.Add(HttpRequestHeader.Authorization, $"Bearer {YfyClientConfig.Oauth2AccessToken}");
            request.Headers.Add("X-Runtime-Version", YfySystem.CallerImageRuntimeVersion);
            request.UserAgent = YfyRequestHandler.UserAgent;
            if (YfyClientConfig.HttpConfig.Proxy != null)
            {
                request.Proxy = YfyClientConfig.HttpConfig.Proxy;
            }

            switch (routeStyle)
            {
            case RouteStyle.Rpc:
            {
                request.ContentType = "application/json";
                request.Accept      = $"application/{this._apiVersion}+json";

                if (requestArg != "")
                {
                    using (Stream bodyStream = request.GetRequestStream())
                    {
                        var bodyBytes = new UTF8Encoding(false).GetBytes(requestArg);
                        bodyStream.Write(bodyBytes, 0, bodyBytes.Length);
                    }
                }
            }
            break;

            case RouteStyle.Upload:
            {
                if (body == null)
                {
                    throw new ArgumentNullException(nameof(body));
                }
                var boundary = YfyRequestHandler._Boundary + DateTime.Now.Ticks.ToString("x");
                request.ContentType = "multipart/form-data; boundary=" + boundary;
                request.SendChunked = true;
                //重要,在上传大文件时该参数应该为false
                request.AllowWriteStreamBuffering = false;

                StringBuilder sb = new StringBuilder("--" + boundary);
                sb.Append("\r\n");
                sb.Append("Content-Disposition: form-data; name=\"file\"; filename=\"\"\r\n");
                sb.Append("Content-Type: application/octet-stream");
                sb.Append("\r\n\r\n");

                var bodyBytes = new UTF8Encoding(false).GetBytes(sb.ToString());
                var endBody   = new UTF8Encoding(false).GetBytes("\r\n" + "--" + boundary + "--");

                using (Stream bodyStream = request.GetRequestStream())
                {
                    bodyStream.Write(bodyBytes, 0, bodyBytes.Length);
                    StreamHelper.CopyStream(body, bodyStream);
                    bodyStream.Write(endBody, 0, endBody.Length);
                }
            }
            break;

            case RouteStyle.Download:
                request.ContentType = null;
                break;

            default:
                throw new ArgumentNullException(nameof(routeStyle));
            }

            try
            {
                response = request.GetResponse() as HttpWebResponse;
                string result;

                if (routeStyle == RouteStyle.Download)
                {
                    using (Stream stream = response.GetResponseStream())
                    {
                        using (FileStream fs = System.IO.File.Create(requestArg))
                        {
                            StreamHelper.CopyStream(stream, fs);
                            result = "";
                        }
                    }
                }
                else
                {
                    result = ReadAsStringFromResponse(response);
                }

                response.Close();
                return(result);
            }
            catch (WebException we)
            {
                response = we.Response as HttpWebResponse;
                if (response == null)
                {
                    throw;
                }

                string responseStr = ReadAsStringFromResponse(response);
                string requestId;
                this.TryGetRequestId(responseStr, out requestId);

                if ((int)response.StatusCode >= 500)
                {
                    throw new RetryException(requestId, (int)response.StatusCode, responseStr, uri, we);
                }
                else if (response.StatusCode == HttpStatusCode.BadRequest)
                {
                    CheckForError(responseStr, uri);
                    throw new BadInputException(requestId, uri, responseStr, we);
                }
                else if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    if (RefreshToken())
                    {
                        throw new TokenRefreshedException();
                    }
                    throw new UnAuthorizedException(requestId, uri, responseStr, we);
                }
                else if ((int)response.StatusCode == RateLimitException.RateLimitStatusCode)
                {
                    int rateLimit = Convert.ToInt32(response.Headers.Get("X-Rate-Limit-Reset"));
                    throw new RateLimitException(requestId, rateLimit, uri, we);
                }
                else if (response.StatusCode == HttpStatusCode.PaymentRequired ||
                         response.StatusCode == HttpStatusCode.Forbidden ||
                         response.StatusCode == HttpStatusCode.Conflict)
                {
                    throw new BadResponseException(requestId, (int)response.StatusCode, uri, responseStr, we);
                }
                else
                {
                    throw new YfyHttpException(requestId, (int)response.StatusCode, uri, we.Message, we);
                }
            }
        }
 public RoutingOptions(float kSpeed, RouteOrientation kOrientation, RouteStyle kRouteStyle)
 {
     this.kSpeed       = kSpeed;
     this.kOrientation = kOrientation;
     this.kRouteStyle  = kRouteStyle;
 }