예제 #1
0
        internal async Task <BinaryResponse> UrlGetToBinaryWithProgress(string request, string referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries)
        {
            if (string.IsNullOrEmpty(request) || (maxTries == 0))
            {
                ArchiLogger.LogNullError(nameof(request) + " || " + nameof(maxTries));

                return(null);
            }

            BinaryResponse result = null;

            for (byte i = 0; i < maxTries; i++)
            {
                const byte printPercentage = 10;
                const byte maxBatches      = 99 / printPercentage;

                using StreamResponse response = await UrlGetToStream(request, referer, requestOptions).ConfigureAwait(false);

                if (response == null)
                {
                    continue;
                }

                if (response.StatusCode.IsClientErrorCode())
                {
                    if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors))
                    {
                        result = new BinaryResponse(response);
                    }

                    break;
                }

                ArchiLogger.LogGenericDebug("0%...");

                using MemoryStream ms = new MemoryStream((int)response.Length);

                try {
                    using Stream contentStream = response.Content;

                    byte   batch         = 0;
                    uint   readThisBatch = 0;
                    byte[] buffer        = new byte[8192];              // This is HttpClient's buffer, using more doesn't make sense

                    while (contentStream.CanRead)
                    {
                        int read = await contentStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);

                        if (read == 0)
                        {
                            break;
                        }

                        await ms.WriteAsync(buffer, 0, read).ConfigureAwait(false);

                        if ((response.Length == 0) || (batch >= maxBatches))
                        {
                            continue;
                        }

                        readThisBatch += (uint)read;

                        if (readThisBatch < response.Length / printPercentage)
                        {
                            continue;
                        }

                        readThisBatch -= response.Length / printPercentage;
                        ArchiLogger.LogGenericDebug((++batch * printPercentage) + "%...");
                    }
                } catch (Exception e) {
                    ArchiLogger.LogGenericDebuggingException(e);

                    return(null);
                }

                ArchiLogger.LogGenericDebug("100%");

                return(new BinaryResponse(response, ms.ToArray()));
            }

            if (maxTries > 1)
            {
                ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, maxTries));
                ArchiLogger.LogGenericDebug(string.Format(Strings.ErrorFailingRequest, request));
            }

            return(result);
        }