/// <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(); } } }
/// <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(); } } }