Ejemplo n.º 1
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);
            }

            if (this.pathRoot != null)
            {
                request.Headers.TryAddWithoutValidation(
                    "Dropbox-Api-Path-Root",
                    JsonWriter.Write(this.pathRoot, PathRoot.Encoder));
            }

            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 ((int)response.StatusCode == 422)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    throw PathRootException.Decode(reason, () => new PathRootException(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();
                }
            }
        }
Ejemplo n.º 2
0
        /// <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.options.HostMap[host];
            var uri      = this.GetRouteUri(hostname, routeName);

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

            if (host != HostType.ApiNotify)
            {
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", this.options.OAuth2AccessToken);
            }

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

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

            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);
                completionOption = HttpCompletionOption.ResponseHeadersRead;
                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.options.HttpClient
                                  .SendAsync(request, completionOption)
                                  .ConfigureAwait(false);

            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 reason = await response.Content.ReadAsStringAsync();

                    throw AuthException.Decode(reason);
                }
                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();
                }
            }
        }