Esempio n. 1
0
        /// <summary>
        /// Reads the file from the server url.
        /// In case of errors reading the file from the server, returned <see cref="T:Coding4Fun.VisualStudio.RemoteControl.GetFileResult" /> object's
        /// IsSuccessStatusCode value will be false.
        /// </summary>
        /// <returns>Information about the file obtained from the server</returns>
        async Task <GetFileResult> IRemoteControlHTTPRequestor.GetFileFromServerAsync()
        {
            GetFileResult result = new GetFileResult
            {
                Code = HttpStatusCode.Unused
            };

            try
            {
                int i = 0;
                while (true)
                {
                    if (i >= 2)
                    {
                        return(result);
                    }
                    if (i > 0)
                    {
                        int num = Math.Min(32, (int)Math.Pow(2.0, i));
                        try
                        {
                            await Task.Delay(num * 1000, cancellationTokenSource.Token).ConfigureAwait(false);
                        }
                        catch (OperationCanceledException)
                        {
                            return(result);
                        }
                        catch (ObjectDisposedException)
                        {
                            return(result);
                        }
                        result.Dispose();
                    }
                    result = await GetFile(url, httpRequestTimeoutMillis, ServerRevalidatePolicy).ConfigureAwait(false);

                    if (result.IsSuccessStatusCode)
                    {
                        break;
                    }
                    i++;
                }
                return(result);
            }
            finally
            {
                if (!result.IsSuccessStatusCode && Platform.IsWindows)
                {
                    WinINetHelper.WriteErrorResponseToCache(errorMarkerFileUrl, result.Code);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// This is the HTTP-facing method in the class. It essentially performs all functions of
        ///     1. sending an HTTP request for the file
        ///     2. if the response is from the server, ensuring that it is added to the IE cache
        ///     3. additonal logic to cache error responses in the IE cache. By default error
        ///        responses are not cached.
        /// </summary>
        /// <param name="requestUrl"></param>
        /// <param name="requestTimeoutMillis"></param>
        /// <param name="cachePolicy">Specifies chache policy to use when sending the request</param>
        /// <returns>Result of the file lookup. See <see cref="T:Coding4Fun.VisualStudio.RemoteControl.GetFileResult" /> for details.</returns>
        private async Task <GetFileResult> GetFile(string requestUrl, int requestTimeoutMillis, HttpRequestCachePolicy cachePolicy)
        {
            HttpWebRequest request = CreateHttpRequest(requestUrl);

            if (request == null)
            {
                return(new GetFileResult
                {
                    ErrorMessage = "Create HTTP Request Error",
                    Code = HttpStatusCode.Unused
                });
            }
            request.Timeout                = requestTimeoutMillis;
            request.CachePolicy            = (cachePolicy ?? new HttpRequestCachePolicy(HttpCacheAgeControl.MaxStale, TimeSpan.MaxValue));
            request.AutomaticDecompression = (DecompressionMethods.GZip | DecompressionMethods.Deflate);
            HttpWebResponse resp      = null;
            WebException    exception = null;

            try
            {
                Task <WebResponse> requestTask = request.GetResponseAsync();
                bool shouldAbort = false;
                try
                {
                    if (await Task.WhenAny(requestTask, Task.Delay(requestTimeoutMillis, cancellationTokenSource.Token)).ConfigureAwait(false) != requestTask)
                    {
                        shouldAbort = true;
                    }
                }
                catch (Exception)
                {
                    shouldAbort = true;
                }
                if (shouldAbort)
                {
                    request.Abort();
                    requestTask.SwallowException();
                    return(new GetFileResult
                    {
                        ErrorMessage = "Request timed out",
                        Code = HttpStatusCode.Unused
                    });
                }
                _    = resp;
                resp = (HttpWebResponse)(await requestTask.ConfigureAwait(false));
            }
            catch (WebException ex2)
            {
                exception = ex2;
            }
            catch (Exception ex3)
            {
                return(new GetFileResult
                {
                    ErrorMessage = "Unknown Exception: " + ex3.Message,
                    Code = HttpStatusCode.Unused
                });
            }
            string errorMessage2 = null;

            if (exception != null)
            {
                WebExceptionStatus status = exception.Status;
                if (status != WebExceptionStatus.ProtocolError)
                {
                    errorMessage2 = string.Format(CultureInfo.InvariantCulture, "Non-Protocol Error {0}", new object[1]
                    {
                        Enum.GetName(typeof(WebExceptionStatus), exception.Status)
                    });
                    return(new GetFileResult
                    {
                        ErrorMessage = errorMessage2,
                        Code = HttpStatusCode.Unused
                    });
                }
                resp          = (exception.Response as HttpWebResponse);
                errorMessage2 = string.Format(CultureInfo.InvariantCulture, "Protocol Error {0}", new object[1]
                {
                    Enum.GetName(typeof(HttpStatusCode), resp.StatusCode)
                });
            }
            if (resp != null)
            {
                int?   ageInSeconds = ExtractAgeHeaderValue(resp);
                Stream stream       = null;
                bool   shouldDisposeResponseStream = false;
                try
                {
                    if (!resp.IsFromCache)
                    {
                        shouldDisposeResponseStream = true;
                        switch (resp.StatusCode)
                        {
                        case HttpStatusCode.OK:
                            stream = await Task.Run(() => CopyToFileStream(resp.GetResponseStream())).ConfigureAwait(false);

                            break;

                        case HttpStatusCode.NotFound:
                            if (Platform.IsWindows)
                            {
                                WinINetHelper.WriteErrorResponseToCache(requestUrl, HttpStatusCode.NotFound);
                            }
                            break;
                        }
                    }
                    return(new GetFileResult
                    {
                        Code = resp.StatusCode,
                        RespStream = ((resp.StatusCode == HttpStatusCode.OK) ? (stream ?? resp.GetResponseStream()) : null),
                        AgeSeconds = ageInSeconds,
                        IsFromCache = resp.IsFromCache,
                        ErrorMessage = errorMessage2
                    });
                }
                catch (UnauthorizedAccessException ex4)
                {
                    shouldDisposeResponseStream = true;
                    errorMessage2 = ex4.Message;
                }
                catch (OperationCanceledException)
                {
                    shouldDisposeResponseStream = true;
                    errorMessage2 = "Download was cancelled by caller";
                }
                catch (ObjectDisposedException)
                {
                    shouldDisposeResponseStream = true;
                    errorMessage2 = "Download was cancelled by caller";
                }
                catch (WebException)
                {
                    shouldDisposeResponseStream = true;
                    errorMessage2 = "Reading HTTP response stream throws an WebException";
                }
                finally
                {
                    if (shouldDisposeResponseStream || resp.StatusCode != HttpStatusCode.OK)
                    {
                        resp.GetResponseStream()?.Dispose();
                    }
                }
                return(new GetFileResult
                {
                    ErrorMessage = errorMessage2,
                    Code = HttpStatusCode.Unused
                });
            }
            throw new InvalidOperationException("WebException is protocol, but response is null", exception);
        }