Beispiel #1
0
        public async Task<IResponse> Send(IRequest request, System.Threading.CancellationToken cancellationToken)
        {
            if (request.Method != HttpMethod.Get)
                return await _httpClient.Send(request, cancellationToken);

            var key = "octokit_cache_" + new Uri(request.BaseAddress, request.Endpoint).AbsoluteUri;
            var cachedResponse = await BlobCache.LocalMachine.GetObject<InternalResponse>(key).Catch(Observable.Empty<InternalResponse>()).DefaultIfEmpty();

            if (cachedResponse == null)
            {
                var httpResponse = await _httpClient.Send(request, cancellationToken);
                cachedResponse = new InternalResponse(httpResponse);
                await BlobCache.LocalMachine.InsertObject(key, cachedResponse, TimeSpan.FromMinutes(30));
                return httpResponse;
            }

            if (!String.IsNullOrEmpty(cachedResponse.ApiInfo.Etag))
            {
                request.Headers["If-None-Match"] = String.Format("{0}", cachedResponse.ApiInfo.Etag);
                var conditionalResponse = await _httpClient.Send(request, cancellationToken);
                if (conditionalResponse.StatusCode == HttpStatusCode.NotModified)
                    return new Response(cachedResponse);

                var newResponse = new InternalResponse(conditionalResponse);
                await BlobCache.LocalMachine.InsertObject(key, newResponse, TimeSpan.FromMinutes(30));
                return conditionalResponse;
            }

            var resp = await _httpClient.Send(request, cancellationToken);
            cachedResponse = new InternalResponse(resp);
            await BlobCache.LocalMachine.InsertObject(key, cachedResponse, TimeSpan.FromMinutes(30));
            return resp;
        }
Beispiel #2
0
 public Response(InternalResponse internalResponse)
 {
     Headers = new ReadOnlyDictionary<string, string>(internalResponse.Headers);
     Body = internalResponse.Body;
     ApiInfo = internalResponse.ApiInfo;
     StatusCode = internalResponse.StatusCode;
     ContentType = internalResponse.ContentType;
 }
Beispiel #3
0
 public Response(InternalResponse internalResponse)
 {
     Headers     = new ReadOnlyDictionary <string, string>(internalResponse.Headers);
     Body        = internalResponse.Body;
     ApiInfo     = internalResponse.ApiInfo;
     StatusCode  = internalResponse.StatusCode;
     ContentType = internalResponse.ContentType;
 }
Beispiel #4
0
        public async Task <IResponse> Send(IRequest request, System.Threading.CancellationToken cancellationToken)
        {
            if (request.Method != HttpMethod.Get)
            {
                return(await _httpClient.Send(request, cancellationToken));
            }

            var key            = "octokit_cache_" + new Uri(request.BaseAddress, request.Endpoint).AbsoluteUri;
            var cachedResponse = await BlobCache.LocalMachine.GetObject <InternalResponse>(key).Catch(Observable.Empty <InternalResponse>()).DefaultIfEmpty();

            if (cachedResponse == null)
            {
                var httpResponse = await _httpClient.Send(request, cancellationToken);

                cachedResponse = new InternalResponse(httpResponse);
                await BlobCache.LocalMachine.InsertObject(key, cachedResponse, TimeSpan.FromMinutes(30));

                return(httpResponse);
            }

            if (!String.IsNullOrEmpty(cachedResponse.ApiInfo.Etag))
            {
                request.Headers["If-None-Match"] = String.Format("{0}", cachedResponse.ApiInfo.Etag);
                var conditionalResponse = await _httpClient.Send(request, cancellationToken);

                if (conditionalResponse.StatusCode == HttpStatusCode.NotModified)
                {
                    return(new Response(cachedResponse));
                }

                var newResponse = new InternalResponse(conditionalResponse);
                await BlobCache.LocalMachine.InsertObject(key, newResponse, TimeSpan.FromMinutes(30));

                return(conditionalResponse);
            }

            var resp = await _httpClient.Send(request, cancellationToken);

            cachedResponse = new InternalResponse(resp);
            await BlobCache.LocalMachine.InsertObject(key, cachedResponse, TimeSpan.FromMinutes(30));

            return(resp);
        }
Beispiel #5
0
        static async Task <(Request Request, string RequestUrl, Response Response)> AfterRequestAsync(
            Request request,
            string requestUrl,
            InternalResponse internalResponse,
            RetryContext retryContext)
        {
            var services         = request.Services;
            var responseMessage  = internalResponse.ResponseMessage;
            var contentTypeValue = default(string);
            var responseContent  = default(IContent);
            var responseHeaders  = default(IReadOnlyDictionary <string, string>);
            var statusCode       = internalResponse.ResponseMessage?.StatusCode ?? default(HttpStatusCode);
            var success          = (int)statusCode >= 200 && (int)statusCode < 300;
            var exception        = internalResponse.Exception;
            var errorMessage     = default(string);

            if (internalResponse.RequestTimeout)
            {
                success      = false;
                errorMessage = "Timed out while making request";

                // The previous code would not show the exception on timeouts.
                exception = null;

                var timeoutRetryEnabled = (services.RetryStrategy?.ShouldRetryOnTimeout ?? false);
                if (timeoutRetryEnabled && retryContext.RetryFailure())
                {
                    bool shouldRetry;
                    (request, requestUrl, shouldRetry) = await ApplyBeforeRetryHandlers(request.Services.BeforeRetryHandlers,
                                                                                        request,
                                                                                        requestUrl,
                                                                                        0,
                                                                                        retryContext.FailureRetryCount);

                    if (shouldRetry)
                    {
                        return(request, requestUrl, null);
                    }
                }
            }
            else if (exception != null)
            {
                success      = false;
                errorMessage = exception.Message;
            }

            if ((services.AuthorizationStrategy?.ShouldReauthorize(statusCode) ?? false) &&
                retryContext.RetryAuthFailure())
            {
                await services.AuthorizationStrategy.Reauthorize();

                return(request, requestUrl, null);
            }

            if ((services.RetryStrategy?.ShouldRetry(statusCode) ?? false) &&
                retryContext.RetryFailure())
            {
                bool shouldRetry;
                (request, requestUrl, shouldRetry) = await ApplyBeforeRetryHandlers(request.Services.BeforeRetryHandlers,
                                                                                    request,
                                                                                    requestUrl,
                                                                                    statusCode,
                                                                                    retryContext.FailureRetryCount);

                if (shouldRetry)
                {
                    return(request, requestUrl, null);
                }
            }

            if (responseMessage != null)
            {
                responseHeaders = responseMessage.Headers.ToDictionary(kv => kv.Key,
                                                                       kv => kv.Value.FirstOrDefault());

                contentTypeValue = responseMessage.Content.Headers
                                   .TryGetValues("Content-Type", out var values) ?
                                   values.FirstOrDefault() :
                                   null;

                responseContent = new StreamedContent(await responseMessage.Content.ReadAsStreamAsync());
            }

            var response = await ApplyAfterResponseHandlers(services.AfterResponseHandlers,
                                                            request,
                                                            new Response(statusCode : statusCode,
                                                                         headers : responseHeaders,
                                                                         content : responseContent,
                                                                         contentType : contentTypeValue,
                                                                         // This was previously always null, should we deprecate this property?
                                                                         contentEncoding : default,
 public async Task <Stream> GetResponseStreamAsync()
 {
     return(InternalResponse.GetResponseStream());
 }