/// <summary> /// Retrieves a thumbnail, or smaller image representation, of this file. Sizes of 32x32, /// 64x64, 128x128, and 256x256 can be returned in the .png format /// and sizes of 32x32, 94x94, 160x160, and 320x320 can be returned in the .jpg format. /// Thumbnails can be generated for the image and video file formats listed here. /// <see cref="http://community.box.com/t5/Managing-Your-Content/What-file-types-are-supported-by-Box-s-Content-Preview/ta-p/327"/> /// </summary> /// <param name="id">Id of the file.</param> /// <param name="minHeight">The minimum height of the thumbnail.</param> /// <param name="minWidth">The minimum width of the thumbnail.</param> /// <param name="maxHeight">The maximum height of the thumbnail.</param> /// <param name="maxWidth">The maximum width of the thumbnail.</param> /// <param name="handleRetry">Specifies whether the method handles retries. If true, then the method would retry the call if the HTTP response is 'Accepted'. The delay for the retry is determined /// by the RetryAfter header, or if that header is not set, by the constant DefaultRetryDelay.</param> /// <param name="throttle">Whether the requests will be throttled. Recommended to be left true to prevent spamming the server.</param> /// <returns>Contents of thumbnail as Stream.</returns> public async Task <Stream> GetThumbnailAsync(string id, int?minHeight = null, int?minWidth = null, int?maxHeight = null, int?maxWidth = null, bool throttle = true, bool handleRetry = true) { id.ThrowIfNullOrWhiteSpace("id"); BoxRequest request = new BoxRequest(_config.FilesEndpointUri, string.Format(Constants.ThumbnailPathString, id)) .Param("min_height", minHeight.ToString()) .Param("min_width", minWidth.ToString()) .Param("max_height", maxHeight.ToString()) .Param("max_width", maxWidth.ToString()); IBoxResponse <Stream> response = await ToResponseAsync <Stream>(request, throttle).ConfigureAwait(false); while (response.StatusCode == HttpStatusCode.Accepted && handleRetry) { await CrossPlatform.Delay(GetTimeDelay(response.Headers)); response = await ToResponseAsync <Stream>(request, throttle).ConfigureAwait(false); } return(response.ResponseObject); }
private async Task <IBoxResponse <Stream> > GetPreviewResponseAsync(string id, int page, int?maxWidth = null, int?minWidth = null, int?maxHeight = null, int?minHeight = null, bool handleRetry = true) { id.ThrowIfNullOrWhiteSpace("id"); BoxRequest request = new BoxRequest(_config.FilesEndpointUri, string.Format(Constants.PreviewPathString, id)) .Param("page", page.ToString()) .Param("max_width", maxWidth.ToString()) .Param("max_height", maxHeight.ToString()) .Param("min_width", minWidth.ToString()) .Param("min_height", minHeight.ToString()); var response = await ToResponseAsync <Stream>(request).ConfigureAwait(false); while (response.StatusCode == HttpStatusCode.Accepted && handleRetry) { await CrossPlatform.Delay(GetTimeDelay(response.Headers)); response = await ToResponseAsync <Stream>(request).ConfigureAwait(false); } return(response); }
public async Task <IBoxResponse <T> > ExecuteAsync <T>(IBoxRequest request) where T : class { // Need to account for special cases when the return type is a stream bool isStream = typeof(T) == typeof(Stream); var numRetries = 3; try { // TODO: yhu@ better handling of different request var isMultiPartRequest = request.GetType() == typeof(BoxMultiPartRequest); var isBinaryRequest = request.GetType() == typeof(BoxBinaryRequest); while (true) { HttpRequestMessage httpRequest = null; if (isMultiPartRequest) { httpRequest = BuildMultiPartRequest(request as BoxMultiPartRequest); } else if (isBinaryRequest) { httpRequest = BuildBinaryRequest(request as BoxBinaryRequest); } else { httpRequest = BuildRequest(request); } // Add headers foreach (var kvp in request.HttpHeaders) { // They could not be added to the headers directly if (kvp.Key == Constants.RequestParameters.ContentMD5 || kvp.Key == Constants.RequestParameters.ContentRange) { httpRequest.Content.Headers.Add(kvp.Key, kvp.Value); } else { httpRequest.Headers.TryAddWithoutValidation(kvp.Key, kvp.Value); } } // If we are retrieving a stream, we should return without reading the entire response HttpCompletionOption completionOption = isStream ? HttpCompletionOption.ResponseHeadersRead : HttpCompletionOption.ResponseContentRead; Debug.WriteLine(string.Format("RequestUri: {0}", httpRequest.RequestUri));//, RequestHeader: {1} , httpRequest.Headers.Select(i => string.Format("{0}:{1}", i.Key, i.Value)).Aggregate((i, j) => i + "," + j))); HttpClient client = GetClient(request); // Not disposing the reponse since it will affect stream response var response = await client.SendAsync(httpRequest, completionOption).ConfigureAwait(false); //need to wait for Retry-After seconds and then retry request var retryAfterHeader = response.Headers.RetryAfter; // If we get a 429 error code and this is not a multi part request (meaning a file upload, which cannot be retried // because the stream cannot be reset) and we haven't exceeded the number of allowed retries, then retry the request. // If we get a 202 code and has a retry-after header, we will retry after if ( ((response.StatusCode == TooManyRequests && !isMultiPartRequest) || (response.StatusCode == HttpStatusCode.Accepted && retryAfterHeader != null)) && numRetries-- > 0) { TimeSpan delay = TimeSpan.FromSeconds(2); if (retryAfterHeader.Delta.HasValue) { delay = retryAfterHeader.Delta.Value; } Debug.WriteLine("HttpCode : {0}. Waiting for {1} seconds to retry request. RequestUri: {2}", response.StatusCode, delay.Seconds, httpRequest.RequestUri); await CrossPlatform.Delay(delay); } else { BoxResponse <T> boxResponse = new BoxResponse <T>(); boxResponse.Headers = response.Headers; // Translate the status codes that interest us boxResponse.StatusCode = response.StatusCode; switch (response.StatusCode) { case HttpStatusCode.OK: case HttpStatusCode.Created: case HttpStatusCode.NoContent: case HttpStatusCode.Found: boxResponse.Status = ResponseStatus.Success; break; case HttpStatusCode.Accepted: boxResponse.Status = ResponseStatus.Pending; break; case HttpStatusCode.Unauthorized: boxResponse.Status = ResponseStatus.Unauthorized; break; case HttpStatusCode.Forbidden: boxResponse.Status = ResponseStatus.Forbidden; break; case TooManyRequests: boxResponse.Status = ResponseStatus.TooManyRequests; break; default: boxResponse.Status = ResponseStatus.Error; break; } if (isStream && boxResponse.Status == ResponseStatus.Success) { var resObj = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); boxResponse.ResponseObject = resObj as T; } else { boxResponse.ContentString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); } return(boxResponse); } } } catch (Exception ex) { Debug.WriteLine(string.Format("Exception: {0}", ex.Message)); throw; } }
public async Task <IBoxResponse <T> > ExecuteAsync <T>(IBoxRequest request) where T : class { // Need to account for special cases when the return type is a stream bool isStream = typeof(T) == typeof(Stream); var numRetries = 3; try { while (true) { HttpRequestMessage httpRequest = request.GetType() == typeof(BoxMultiPartRequest) ? BuildMultiPartRequest(request as BoxMultiPartRequest) : BuildRequest(request); // Add headers foreach (var kvp in request.HttpHeaders) { if (kvp.Key == Constants.RequestParameters.ContentMD5) { httpRequest.Content.Headers.Add(kvp.Key, kvp.Value); } else { httpRequest.Headers.TryAddWithoutValidation(kvp.Key, kvp.Value); } } // If we are retrieving a stream, we should return without reading the entire response HttpCompletionOption completionOption = isStream ? HttpCompletionOption.ResponseHeadersRead : HttpCompletionOption.ResponseContentRead; Debug.WriteLine(string.Format("RequestUri: {0}", httpRequest.RequestUri));//, RequestHeader: {1} , httpRequest.Headers.Select(i => string.Format("{0}:{1}", i.Key, i.Value)).Aggregate((i, j) => i + "," + j))); HttpClient client = CreateClient(request); BoxResponse <T> boxResponse = new BoxResponse <T>(); HttpResponseMessage response = await client.SendAsync(httpRequest, completionOption).ConfigureAwait(false); if (response.StatusCode == TooManyRequests && numRetries-- > 0) { //need to wait for Retry-After seconds and then retry request var retryAfterHeader = response.Headers.RetryAfter; TimeSpan delay; if (retryAfterHeader.Delta.HasValue) { delay = retryAfterHeader.Delta.Value; } else { delay = TimeSpan.FromMilliseconds(2000); } Debug.WriteLine("TooManyRequests error (429). Waiting for {0} seconds to retry request. RequestUri: {1}", delay.Seconds, httpRequest.RequestUri); await CrossPlatform.Delay(Convert.ToInt32(delay.TotalMilliseconds)); } else { boxResponse.Headers = response.Headers; // Translate the status codes that interest us boxResponse.StatusCode = response.StatusCode; switch (response.StatusCode) { case HttpStatusCode.OK: case HttpStatusCode.Created: case HttpStatusCode.NoContent: case HttpStatusCode.Found: boxResponse.Status = ResponseStatus.Success; break; case HttpStatusCode.Accepted: boxResponse.Status = ResponseStatus.Pending; break; case HttpStatusCode.Unauthorized: boxResponse.Status = ResponseStatus.Unauthorized; break; case HttpStatusCode.Forbidden: boxResponse.Status = ResponseStatus.Forbidden; break; case TooManyRequests: boxResponse.Status = ResponseStatus.TooManyRequests; break; default: boxResponse.Status = ResponseStatus.Error; break; } if (isStream && boxResponse.Status == ResponseStatus.Success) { var resObj = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); boxResponse.ResponseObject = resObj as T; } else { boxResponse.ContentString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); } return(boxResponse); } } } catch (Exception ex) { Debug.WriteLine(string.Format("Exception: {0}", ex.Message)); throw; } }