/// <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;
            }
        }
Beispiel #4
0
        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;
            }
        }